package com.egao.common.module.student.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.*;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.egao.common.component.minio.config.MinioBucket;
import com.egao.common.component.minio.service.MinioService;
import com.egao.common.core.Constants;
import com.egao.common.core.exception.BusinessException;
import com.egao.common.core.exception.ParameterException;
import com.egao.common.core.utils.CoreUtil;
import com.egao.common.core.utils.ExcelUtils;
import com.egao.common.core.utils.StudentSignlogUtil;
import com.egao.common.core.web.JsonResult;
import com.egao.common.core.web.PageParam;
import com.egao.common.core.web.PageResult;
import com.egao.common.module.aolan.service.AoLanService;
import com.egao.common.module.company.entity.Company;
import com.egao.common.module.company.service.CompanyService;
import com.egao.common.module.home.entity.HomeData;
import com.egao.common.module.student.constants.StudentConstants;
import com.egao.common.module.student.constants.StudentSignBlankConstants;
import com.egao.common.module.student.constants.StudentSignConstants;
import com.egao.common.module.student.entity.*;
import com.egao.common.module.student.entity.print.AgilePrintVO;
import com.egao.common.module.student.entity.print.DealPrintVO;
import com.egao.common.module.student.entity.print.FreePrintVO;
import com.egao.common.module.student.entity.print.VenturePrintVO;
import com.egao.common.module.student.entity.vo.*;
import com.egao.common.module.student.mapper.StudentSignBlankMapper;
import com.egao.common.module.student.mapper.StudentSignMapper;
import com.egao.common.module.student.service.*;
import com.egao.common.module.system.constants.DictConstants;
import com.egao.common.module.system.constants.EmailConstants;
import com.egao.common.module.system.constants.UserConstants;
import com.egao.common.module.system.entity.*;
import com.egao.common.module.system.service.*;
import com.egao.common.module.validate.service.ValidateRuleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.*;

/**
 * 学生签约毕业去向接口实现类
 *
 * @author lym
 */
@Service
public class StudentSignServiceImpl extends ServiceImpl<StudentSignMapper, StudentSign> implements StudentSignService {

    @Autowired
    private StudentService studentService;
    @Autowired
    private StudentInfoService studentInfoService;
    @Autowired
    private StudentRecordService studentRecordService;
    @Autowired
    private DictService dictService;
    @Autowired
    private DispatchCompanyService dispatchCompanyService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private QsSchoolService qsSchoolService;
    @Autowired
    private StudentSignSetService studentSignSetService;
    @Autowired
    private YearService yearService;
    @Autowired
    private StudentSignDispatchService studentSignDispatchService;
    @Autowired
    private EmailService emailService;
    @Autowired
    private UserService userService;
    @Autowired
    private AoLanService aoLanService;
    @Autowired
    private StudentSignBlankMapper studentSignBlankMapper;
    @Autowired
    private MinioService minioService;
    @Autowired
    private StudentSignAlterService studentSignAlterService;
    @Resource
    private StudentSignEditService studentSignEditService;
    @Resource
    private ValidateRuleService validateRuleService;

    @Value("${log.path}")
    private String logPath;

    private final Logger logger = LoggerFactory.getLogger(StudentServiceImpl.class.getName());

    @Override
    public PageResult<StudentSignListVO> listPage(PageParam<StudentSign> pageParam) {
        Integer userId = pageParam.getInt("userId");
        Student student = studentService.getByUserId(userId);
        if (student == null) {
            throw new BusinessException("学生信息异常");
        }
        pageParam.put("studentId", student.getId());
        List<StudentSignListVO> studentSignListVOS = baseMapper.listPage(pageParam);
        for (StudentSignListVO vo : studentSignListVOS) {
            vo.setSignExpiredTimeLabel("0");
            if (vo.getSignExpiredTime() == null) {
                vo.setSignExpiredTimeLabel("1");
            } else {
                if (System.currentTimeMillis() > vo.getSignExpiredTime().getTime()) {
                    vo.setSignExpiredTimeLabel("1");
                }
            }
        }
        return new PageResult<>(studentSignListVOS, pageParam.getTotal());
    }

    @Override
    public List<StudentSignListVO> listAll(Integer loginUserId) {
        return null;
    }

    @Override
    public StudentSign getStateValid(Integer loginUserId) {
        return baseMapper.selectOne(new QueryWrapper<StudentSign>()
                .eq("user_id", loginUserId)
                .eq("state", StudentSignConstants.STATE_VALID)
                .orderByDesc("id")
                .last("limit 1")
        );
    }

    @Override
    public JsonResult getSignCategory(Integer loginUserId) {
        // 单位是否修改协议内容 默认否
        boolean editState = false;

        Student student = studentService.getByUserId(loginUserId);

        if (student == null) {
            throw new BusinessException("学生信息异常");
        }

        if (StrUtil.isBlank(student.getSignCategory())) {
            student.setSignCategory(StudentSignConstants.SIGN_CATEGORY_NULL);
        }

        // 判断单位是否修改协议内容并赋值
        StudentSign studentSign = getStateValid(loginUserId);
        if (studentSign != null) {
            StudentSignEdit studentSignEdit = studentSignEditService.getForm(studentSign.getId());
            if (studentSignEdit != null) {
                editState = true;
            }
        }

        return JsonResult.ok().setData(student.getSignCategory()).put("editState", editState);
    }

    @Override
    public JsonResult detail(Integer id, Integer loginUserId, boolean collegeBtn, String userType) {
        StudentSign studentSign = new StudentSign();

        // 邀约信息使用主键查询
        if (id != null) {
            // 根据ID查询
            studentSign = baseMapper.selectById(id);
        } else {
            // 根据登陆人查询
            studentSign = getStateValid(loginUserId);
        }

        if (studentSign == null) {
            throw new BusinessException("没有查询到登记信息");
        }

        if (loginUserId != null && !loginUserId.equals(studentSign.getUserId())) {
            throw new BusinessException("登记信息人异常");
        }

        // 先查询修改版 有就直接用
        StudentSignEdit studentSignEdit = studentSignEditService.getForm(studentSign.getId());
        if (studentSignEdit != null) {
            BeanUtil.copyProperties(studentSignEdit, studentSign);
            studentSign.setEditState("0");
        } else {
            // 对象值
            studentSign = baseMapper.getForm(studentSign);
            studentSign.setEditState("1");
        }

        // 表单标签值
        getFormLabels(studentSign);

        // 表单字典Map
        Map<String, List<Dict>> formMap = getFormMap();
        // 网签SYSZD字典移除北京市、上海市、重庆市、天津市4个直辖市
        List<Dict> syszdList = formMap.get(DictConstants.TYPE_SYSZD);
        List<Dict> removeSyszd = new ArrayList<>();
        for (Dict dict : syszdList) {
            if ("北京市".equals(dict.getLabel()) || "上海市".equals(dict.getLabel()) || "重庆市".equals(dict.getLabel()) || "天津市".equals(dict.getLabel())) {
                removeSyszd.add(dict);
            }
        }
        syszdList.removeAll(removeSyszd);
        formMap.put(DictConstants.TYPE_SYSZD, syszdList);

        // 户口迁转类型根据就业方式添加禁用属性
        List<Dict> hkqzlxList = formMap.get(DictConstants.TYPE_HKQZLX);
        for (Dict dict : hkqzlxList) {
            if (StudentSignConstants.SIGN_CATEGORY_XYJY.equals(studentSign.getSignCategory())) {
                String[] values = new String[]{"4", "5"};
                if (CollectionUtil.contains(Arrays.asList(values), dict.getValue())) {
                    dict.setDisabled(true);
                }
            }
            if (StudentSignConstants.SIGN_CATEGORY_ZZCY.equals(studentSign.getSignCategory())) {
                String[] values = new String[]{"1", "3", "4", "5"};
                if (CollectionUtil.contains(Arrays.asList(values), dict.getValue())) {
                    dict.setDisabled(true);
                }
            }
            if (StudentSignConstants.SIGN_CATEGORY_ZYZY.equals(studentSign.getSignCategory())) {
                String[] values = new String[]{"1", "3", "4", "5"};
                if (CollectionUtil.contains(Arrays.asList(values), dict.getValue())) {
                    dict.setDisabled(true);
                }
            }
            if (StudentSignConstants.SIGN_CATEGORY_SX.equals(studentSign.getSignCategory())) {
                String[] values = new String[]{"1", "2", "3"};
                if (CollectionUtil.contains(Arrays.asList(values), dict.getValue())) {
                    dict.setDisabled(true);
                }
            }
            if (StudentSignConstants.SIGN_CATEGORY_CGCJ.equals(studentSign.getSignCategory())) {
                String[] values = new String[]{"1", "3", "4", "5"};
                if (CollectionUtil.contains(Arrays.asList(values), dict.getValue())) {
                    dict.setDisabled(true);
                }
            }
            if (StudentSignConstants.SIGN_CATEGORY_DJY.equals(studentSign.getSignCategory())) {
                String[] values = new String[]{"1", "3", "4", "5"};
                if (CollectionUtil.contains(Arrays.asList(values), dict.getValue())) {
                    dict.setDisabled(true);
                }
            }
        }

        // 查询图片
        imgPreview(studentSign);

        JsonResult jsonResult = JsonResult.ok();
        // 表单对象
        jsonResult.setData(studentSign);
        // 字典集合
        jsonResult.put("dictMaps", formMap);

        // 出国出境 洲,国家,学校三级树
        if (StudentSignConstants.SIGN_CATEGORY_CGCJ.equals(studentSign.getSignCategory())) {
            jsonResult.put("qsTree", qsSchoolService.treeAll());
        }

        // 学院审核按钮加载
        if (collegeBtn) {
            studentSign.setUserType(userType);
            jsonResult.put("collegeSubmit", buildCollegeSubmit(studentSign));
        }

        // 审核不通过提示
        if (StudentSignConstants.DISPATCH_STATE_COLLEGE_FAIL.equals(studentSign.getDispatchState())) {
            studentSign.setCheckTitle("派遣信息审核不通过，请根据提示修改信息后再提交");
        }
        if (StudentSignConstants.SIGN_STATE_COLLEGE_FAIL.equals(studentSign.getSignState())) {
            studentSign.setCheckTitle("签约(登记)信息审核不通过，当前登记信息已无效，请重置就业方式后再选择应约或选择其他就业方式");
        }
        if (StudentSignConstants.SIGN_STATE_COLLEGE_TERMINATION_FAIL.equals(studentSign.getSignState())) {
            studentSign.setCheckTitle("申请解约审核不通过");
        }
        if (StudentSignConstants.SIGN_STATE_COLLEGE_LEAD_TERMINATION_FAIL.equals(studentSign.getSignState())) {
            studentSign.setCheckTitle("申请解约审核不通过");
        }
        if (StudentSignConstants.DISPATCH_STATE_EDIT_COLLEGE_FAIL.equals(studentSign.getDispatchState())) {
            studentSign.setCheckTitle("申请改派审核不通过");
        }

        // 过期按钮
        JsonResult expired = verifySignExpiredTime(studentSign);
        jsonResult.put("expiredBtn", expired.get("expiredBtn")).put("expiredBtnMsg", expired.get("expiredBtnMsg"));

        return jsonResult;
    }

    private void imgPreview(StudentSign studentSign) {
        String centerImg = studentSign.getCenterImg();
        String centerImgPreview = minioService.getPreSignedObjectUrl(MinioBucket.MINIO_SIGN, centerImg);
        studentSign.setCenterImgPreview(centerImgPreview);

        String abroadOfferImg = studentSign.getAbroadOfferImg();
        String abroadOfferImgPreview = minioService.getPreSignedObjectUrl(MinioBucket.MINIO_SIGN, abroadOfferImg);
        studentSign.setAbroadOfferImgPreview(abroadOfferImgPreview);

        String studyImg = studentSign.getStudyImg();
        String studyImgPreview = minioService.getPreSignedObjectUrl(MinioBucket.MINIO_SIGN, studyImg);
        studentSign.setStudyImgPreview(studyImgPreview);

        String ventureBusinessImg = studentSign.getVentureBusinessImg();
        String ventureBusinessImgPreview = minioService.getPreSignedObjectUrl(MinioBucket.MINIO_SIGN, ventureBusinessImg);
        studentSign.setVentureBusinessImgPreview(ventureBusinessImgPreview);

        String venturePlaceImg = studentSign.getVenturePlaceImg();
        String venturePlaceImgPreview = minioService.getPreSignedObjectUrl(MinioBucket.MINIO_SIGN, venturePlaceImg);
        studentSign.setVenturePlaceImgPreview(venturePlaceImgPreview);

        String terminationImg = studentSign.getTerminationImg();
        String terminationImgPreview = minioService.getPreSignedObjectUrl(MinioBucket.MINIO_SIGN, terminationImg);
        studentSign.setTerminationImgPreview(terminationImgPreview);

        String recordImg = studentSign.getRecordImg();
        String recordImgPreview = minioService.getPreSignedObjectUrl(MinioBucket.MINIO_SIGN, recordImg);
        studentSign.setRecordImgPreview(recordImgPreview);

        String wageImg = studentSign.getWageImg();
        String wageImgPreview = minioService.getPreSignedObjectUrl(MinioBucket.MINIO_SIGN, wageImg);
        studentSign.setWageImgPreview(wageImgPreview);
    }

    @Override
    public JsonResult pickSignCategory(String signCategory, Integer loginUserId) {
        Student student = studentService.getByUserId(loginUserId);

        if (StrUtil.isBlank(signCategory)) {
            throw new BusinessException("就业方式参数异常");
        }

        if (student == null) {
            throw new BusinessException("学生信息异常");
        }

        if (!StrUtil.isBlank(student.getSignCategory())) {
            throw new BusinessException("您已选择了就业方式");
        }

        if (!StudentConstants.STUDENT_SCHOOL_PASS.equals(student.getSchoolState())) {
            throw new BusinessException("请先完成生源并等待学校审核通过");
        }

        JsonResult blankResult = blankVerify(student.getId());
        if (Constants.RESULT_ERROR_CODE == blankResult.getCode()) {
            return blankResult;
        }

        boolean b = studentService.updateSignCategory(signCategory, student.getId());

        if (!b) {
            throw new BusinessException("选择就业方式失败");
        }

        // 除协议就业外其他就业方式插入一条有效毕业去向登记数据
        StudentSign studentSign = new StudentSign();
        studentSign.setUserId(loginUserId);
        studentSign.setStudentId(student.getId());

        studentSign.setSerialNumber(initSerialNumber());
        studentSign.setSignCategory(signCategory);
        studentSign.setSignWay(StudentSignConstants.SIGN_WAY_STUDENT);
        studentSign.setDealCategory(StudentSignConstants.SIGN_DEAL_CATEGORY_FALSE);
        studentSign.setDealRolePick(StudentSignConstants.SIGN_DEAL_ROLE_PICK_STUDENT);
        studentSign.setDispatchHkAddressWho(StudentSignConstants.DISPATCH_HK_ADDRESS_WHO_STUDENT);

        studentSign.setState(StudentSignConstants.STATE_VALID);
        studentSign.setSignState(StudentSignConstants.SIGN_STATE_STUDENT_WAIT);
        studentSign.setDispatchState(StudentSignConstants.DISPATCH_STATE_STUDENT_WAIT);

        if (StudentSignConstants.SIGN_CATEGORY_XYJY.equals(signCategory)) {
            studentSign.setDispatchJobCondition(StudentSignConstants.SIGN_JYZK_XYJY);
            studentSign.setDispatchJobCategory(StudentSignConstants.SIGN_CATEGORY_XYJY);
        }

        if (StudentSignConstants.SIGN_CATEGORY_LHJY.equals(signCategory)) {
            studentSign.setDispatchJobCondition(StudentSignConstants.SIGN_JYZK_LHJY);
            studentSign.setDispatchJobCategory(StudentSignConstants.SIGN_CATEGORY_LHJY);
        }

        if (StudentSignConstants.SIGN_CATEGORY_ZZCY.equals(signCategory)) {
            studentSign.setDispatchJobCondition(StudentSignConstants.SIGN_JYZK_ZZCY);
            studentSign.setDispatchJobCategory(StudentSignConstants.SIGN_CATEGORY_ZZCY);
            studentSign.setDealCompanyNature(StudentSignConstants.SIGN_CATEGORY_ZZCY);
        }

        if (StudentSignConstants.SIGN_CATEGORY_ZYZY.equals(signCategory)) {
            studentSign.setDispatchJobCondition(StudentSignConstants.SIGN_JYZK_ZYZY);
            studentSign.setDispatchJobCategory(StudentSignConstants.SIGN_CATEGORY_ZYZY);
            studentSign.setDealCompanyNature(StudentSignConstants.SIGN_CATEGORY_ZYZY);
        }

        if (StudentSignConstants.SIGN_CATEGORY_SX.equals(signCategory)) {
            studentSign.setDispatchJobCondition(StudentSignConstants.SIGN_JYZK_SX);
            // studentSign.setDispatchJobCategory(StudentSignConstants.SIGN_CATEGORY_SX);
            // 801	录取研究生
            // 802	录取第二学士学位
            studentSign.setDispatchJobCategory("801");
            studentSign.setDealCompanyNature(StudentSignConstants.SIGN_CATEGORY_SX);
        }

        if (StudentSignConstants.SIGN_CATEGORY_CGCJ.equals(signCategory)) {
            studentSign.setDispatchJobCondition(StudentSignConstants.SIGN_JYZK_CGCJ);
            studentSign.setDispatchJobCategory(StudentSignConstants.SIGN_CATEGORY_CGCJ);
            studentSign.setDealCompanyNature(StudentSignConstants.SIGN_CATEGORY_CGCJ);
        }

        if (StudentSignConstants.SIGN_CATEGORY_DJY.equals(signCategory)) {
            studentSign.setDispatchJobCondition(StudentSignConstants.SIGN_JYZK_DJY);
            studentSign.setDispatchJobCategory(StudentSignConstants.SIGN_CATEGORY_DJY);
            studentSign.setDealCompanyNature(StudentSignConstants.SIGN_CATEGORY_DJY);
        }

        studentSign.setAlterState(StudentSignConstants.ALTER_FALSE);
        baseMapper.insert(studentSign);

        studentRecordService.save(
                new StudentRecord(loginUserId, student.getId(), StudentConstants.RECORD_TYPE_SIGN, StudentConstants.RECORD_OPERATE_STUDENT_SIGN_PICK)
        );

        return JsonResult.ok();
    }

    @Override
    public JsonResult resetSignCategory(Integer loginUserId) {
        Student student = studentService.getByUserId(loginUserId);

        if (student == null) {
            throw new BusinessException("学生信息异常");
        }

        if (StrUtil.isBlank(student.getSignCategory())) {
            throw new BusinessException("当前就业方式是初始状态");
        }

        StudentSign studentSign = getStateValid(loginUserId);

        // 没有登记信息直接重置
        if (studentSign == null) {
            ResetSignCategory(loginUserId, student.getId(), "没有登记信息直接重置");
            return JsonResult.ok("重置就业方式成功");
        }

        // 协议就业 只有学生待提交和解约学校审核通过才可以重置就业方式
        if (StudentSignConstants.SIGN_CATEGORY_XYJY.equals(student.getSignCategory())) {
            if (!StudentSignConstants.SIGN_STATE_STUDENT_WAIT.equals(studentSign.getSignState())
                    && !StudentSignConstants.SIGN_STATE_SCHOOL_TERMINATION_PASS.equals(studentSign.getSignState())) {
                throw new BusinessException("已'协议就业'，请解约成功后重置就业方式");
            }
        }

        // 灵活就业 只有学生待提交和解约学校审核通过才可以重置就业方式
        if (StudentSignConstants.SIGN_CATEGORY_LHJY.equals(student.getSignCategory())) {
            if (!StudentSignConstants.SIGN_STATE_STUDENT_WAIT.equals(studentSign.getSignState())
                    && !StudentSignConstants.SIGN_STATE_SCHOOL_TERMINATION_PASS.equals(studentSign.getSignState())) {
                throw new BusinessException("已'灵活就业'，请解约成功后重置就业方式");
            }
        }

        // 更新就业状态
        if (StudentSignConstants.SIGN_CATEGORY_SX.equals(studentSign.getSignCategory())) {
            studentService.updateStatus(student.getId(), StudentConstants.SIGN_STATUS_MANUAL, "", "");
        }

        // 其他就业方式直接重置
        ResetSignCategory(loginUserId, student.getId(), "");

        // 删除奥兰中的毕业去向信息
        aoLanService.delete(student.getYearId(), student.getXh());

        return JsonResult.ok("重置就业方式成功");
    }

    /**
     * 重置就业方式
     * 将所有登记信息改为无效
     * 记录
     *
     * @param loginUserId 登录人ID
     * @param studentId   学生ID
     * @param content     记录说明
     */
    public void ResetSignCategory(Integer loginUserId, Integer studentId, String content) {
        // 重置就业方式
        studentService.updateSignCategory("", studentId);

        // 所有登记信息改为信息无效
        StudentSign studentSign = new StudentSign();
        studentSign.setState(StudentSignConstants.STATE_INVALID);
        baseMapper.update(studentSign, new UpdateWrapper<StudentSign>().eq("user_id", loginUserId));

        // 记录操作
        studentRecordService.save(
                new StudentRecord(loginUserId, studentId, StudentConstants.RECORD_TYPE_SIGN, StudentConstants.RECORD_OPERATE_STUDENT_SIGN_RESET, content)
        );
    }

    @Override
    public JsonResult pickDispatchHiredWay(StudentSign studentSign, Integer loginUserId) {
        Student student = studentService.getByUserId(loginUserId);
        if (student == null) {
            throw new BusinessException("学生异常");
        }

        if (StrUtil.isBlank(student.getSyszd())) {
            throw new BusinessException("学生生源地异常");
        }

        if (studentSign == null) {
            throw new BusinessException("毕业去向参数异常");
        }

        if (StrUtil.isBlank(studentSign.getSignCategory())) {
            throw new BusinessException("就业方式异常");
        }

        String dispatchHiredWay = studentSign.getDispatchHiredWay();

        // 选择了空录用方式 提示不予选择
        if (StrUtil.isBlank(dispatchHiredWay)) {
            throw new BusinessException(Constants.RESULT_CONTINUE_CODE, "请选择其中一项录用方式");
        }

        dispatchClear(studentSign);

        // 协议就业
        if (StudentSignConstants.LYFS_01.equals(dispatchHiredWay)) {
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_HYJ);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_SYDBD);
            JsonResult jsonResult = dispatchCompanyService.getDispatchByCode(studentSign, student.getSyszd());
            if (Constants.RESULT_ERROR_CODE == jsonResult.getCode()) {
                return jsonResult;
            }
        }

        if (StudentSignConstants.LYFS_02.equals(dispatchHiredWay)) {
            dispatchHiredWayHuBei(studentSign);
        }

        if (StudentSignConstants.LYFS_03.equals(dispatchHiredWay)) {
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_PQ);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_DLDBD);
        }

        if (StudentSignConstants.LYFS_04.equals(dispatchHiredWay)) {
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_PQ);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_DLDBD);
        }

        if (StudentSignConstants.LYFS_05.equals(dispatchHiredWay)) {
            dispatchHiredWayWuHan(studentSign);
        }

        if (StudentSignConstants.LYFS_06.equals(dispatchHiredWay)) {

        }

        // 灵活就业
        if (StudentSignConstants.LYFS_07.equals(dispatchHiredWay)) {
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_HYJ);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_SYDBD);
            JsonResult jsonResult = dispatchCompanyService.getDispatchByCode(studentSign, student.getSyszd());
            if (Constants.RESULT_ERROR_CODE == jsonResult.getCode()) {
                return jsonResult;
            }
        }

        if (StudentSignConstants.LYFS_08.equals(dispatchHiredWay)) {
            dispatchHiredWayHuBei(studentSign);
        }

        if (StudentSignConstants.LYFS_09.equals(dispatchHiredWay)) {
            dispatchHiredWayWuHan(studentSign);
        }

        // 升学
        if (StudentSignConstants.LYFS_10.equals(dispatchHiredWay)) {
            studentSign.setDispatchJobCategory("802");
            studentSign.setDispatchJobCategoryLabel("第二学士学位");
            studentSign.setStudySchoolAdmissionWay(StudentSignConstants.SIGN_STUDY_SCHOOL_ADMISSION_WAY_3);
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_SX);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_WQFBDZ);
        }

        if (StudentSignConstants.LYFS_11.equals(dispatchHiredWay)) {
            studentSign.setDispatchJobCategory("801");
            studentSign.setDispatchJobCategoryLabel("研究生");
            studentSign.setStudySchoolAdmissionWay(StudentSignConstants.SIGN_STUDY_SCHOOL_ADMISSION_WAY_2);
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_HYJ);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_SYDBD);
            JsonResult jsonResult = dispatchCompanyService.getDispatchByCode(studentSign, student.getSyszd());
            if (Constants.RESULT_ERROR_CODE == jsonResult.getCode()) {
                return jsonResult;
            }
        }

        if (StudentSignConstants.LYFS_12.equals(dispatchHiredWay)) {
            studentSign.setDispatchJobCategory("801");
            studentSign.setDispatchJobCategoryLabel("研究生");
            studentSign.setStudySchoolAdmissionWay(StudentSignConstants.SIGN_STUDY_SCHOOL_ADMISSION_WAY_2);
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_SX);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_WQFBDZ);
            dispatchHiredWaySxZuel(studentSign);
        }

        if (StudentSignConstants.LYFS_13.equals(dispatchHiredWay)) {
            studentSign.setDispatchJobCategory("801");
            studentSign.setDispatchJobCategoryLabel("研究生");
            studentSign.setStudySchoolAdmissionWay(StudentSignConstants.SIGN_STUDY_SCHOOL_ADMISSION_WAY_1);
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_SX);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_WQFBDZ);
            dispatchHiredWaySxZuel(studentSign);
        }

        if (StudentSignConstants.LYFS_14.equals(dispatchHiredWay)) {
            studentSign.setDispatchJobCategory("801");
            studentSign.setDispatchJobCategoryLabel("研究生");
            studentSign.setStudySchoolAdmissionWay(StudentSignConstants.SIGN_STUDY_SCHOOL_ADMISSION_WAY_2);
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_SX);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_WQFBDZ);
            dispatchHiredWaySxZuel(studentSign);
        }

        if (StudentSignConstants.LYFS_99.equals(dispatchHiredWay)) {
            studentSign.setDispatchJobCategory("801");
            studentSign.setDispatchJobCategoryLabel("研究生");
            studentSign.setStudySchoolAdmissionWay(StudentSignConstants.SIGN_STUDY_SCHOOL_ADMISSION_WAY_2);
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_SX);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_WQFBDZ);
        }

        // 自由职业
        if (StudentSignConstants.LYFS_15.equals(dispatchHiredWay)) {
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_PQ);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_DLDBD);
        }

        if (StudentSignConstants.LYFS_16.equals(dispatchHiredWay)) {
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_HYJ);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_SYDBD);
            JsonResult jsonResult = dispatchCompanyService.getDispatchByCode(studentSign, student.getSyszd());
            if (Constants.RESULT_ERROR_CODE == jsonResult.getCode()) {
                return jsonResult;
            }
        }

        if (StudentSignConstants.LYFS_17.equals(dispatchHiredWay)) {
            dispatchHiredWayWuHan(studentSign);
        }

        // 自主创业
        if (StudentSignConstants.LYFS_18.equals(dispatchHiredWay)) {
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_HYJ);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_SYDBD);
            JsonResult jsonResult = dispatchCompanyService.getDispatchByCode(studentSign, student.getSyszd());
            if (Constants.RESULT_ERROR_CODE == jsonResult.getCode()) {
                return jsonResult;
            }
        }

        if (StudentSignConstants.LYFS_19.equals(dispatchHiredWay)) {
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_PQ);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_DLDBD);
        }

        if (StudentSignConstants.LYFS_20.equals(dispatchHiredWay)) {
            dispatchHiredWayWuHan(studentSign);
        }

        // 出国出境
        if (StudentSignConstants.LYFS_21.equals(dispatchHiredWay)) {
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_HYJ);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_SYDBD);
            JsonResult jsonResult = dispatchCompanyService.getDispatchByCode(studentSign, student.getSyszd());
            if (Constants.RESULT_ERROR_CODE == jsonResult.getCode()) {
                return jsonResult;
            }
        }

        if (StudentSignConstants.LYFS_22.equals(dispatchHiredWay)) {
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_PQ);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_DLDBD);
        }

        if (StudentSignConstants.LYFS_26.equals(dispatchHiredWay)) {
            dispatchHiredWayWuHan(studentSign);
        }

        // 待就业
        if (StudentSignConstants.LYFS_23.equals(dispatchHiredWay)) {
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_HYJ);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_SYDBD);
            JsonResult jsonResult = dispatchCompanyService.getDispatchByCode(studentSign, student.getSyszd());
            if (Constants.RESULT_ERROR_CODE == jsonResult.getCode()) {
                return jsonResult;
            }
        }

        if (StudentSignConstants.LYFS_24.equals(dispatchHiredWay)) {
            studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_PQ);
            studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_DLDBD);
        }

        if (StudentSignConstants.LYFS_25.equals(dispatchHiredWay)) {
            dispatchHiredWayWuHan(studentSign);
        }

        return JsonResult.ok().setData(studentSign);
    }

    @Override
    public JsonResult submit(StudentSign studentSign, Integer loginUserId) {
        StudentSignlogUtil.log(logPath, studentSign, "学生初始提交");

        Student student = studentService.getByUserId(loginUserId);

        if (student == null) {
            throw new BusinessException("学生信息异常");
        }

        if (studentSign == null) {
            throw new BusinessException("提交信息异常");
        }

        if (!loginUserId.equals(studentSign.getUserId())) {
            throw new BusinessException("学生毕业去向信息异常");
        }

        StudentSign old = baseMapper.selectById(studentSign.getId());
        if (old == null) {
            throw new BusinessException("毕业去向信息异常");
        }

        // 非网签单位存在不可自主录入
        if (StudentSignConstants.SIGN_DEAL_CATEGORY_FALSE.equals(studentSign.getDealCategory())
                && !StrUtil.isBlank(studentSign.getDealCompanyOrganizationCode())) {
            Company company = companyService.getCompanyByOrganizationCode(studentSign.getDealCompanyOrganizationCode());
            // 单位存在 且 学生自由自主录入标记为否 且 不是学院退回状态
            if (company != null && StudentConstants.SIGN_ENTRY_FALSE.equals(student.getSignEntry())
                    && !StudentSignConstants.DISPATCH_STATE_COLLEGE_FAIL.equals(studentSign.getDispatchState())) {
                throw new BusinessException("单位已在本校注册，请联系单位使用本系统向你邀约走网上签约流程");
            }
        }

        // 验证协议就业、灵活就业组织机构代码格式是否正确
        if (StudentSignConstants.SIGN_CATEGORY_XYJY.equals(studentSign.getSignCategory())
                || StudentSignConstants.SIGN_CATEGORY_LHJY.equals(studentSign.getSignCategory())) {
            // 是否出国出境工作为空或者为否时需要验证单位组织机构代码
            if (StrUtil.isBlank(studentSign.getGoAbroad()) || "1".equals(studentSign.getGoAbroad())) {
                if (StrUtil.isBlank(studentSign.getDealCompanyOrganizationCode())) {
                    throw new BusinessException("单位组织机构代码不能为空");
                }
                if (!companyService.isCreditCode(studentSign.getDealCompanyOrganizationCode())) {
                    throw new BusinessException("单位组织机构代码格式不正确");
                }
            }
        }

        // 升学验证
        String dispatchHiredWay = studentSign.getDispatchHiredWay();
        if (StudentSignConstants.SIGN_CATEGORY_SX.equals(studentSign.getSignCategory())) {
            // 非全日制报到证签发类别不能是托管
            if (StudentSignConstants.LYFS_11.equals(dispatchHiredWay)
                    || StudentSignConstants.LYFS_12.equals(dispatchHiredWay)) {
                if (StudentSignConstants.SIGN_BDZQFLB_DLDBD.equals(studentSign.getDispatchReportIssuedCategory())) {
                    throw new BusinessException("升学 录取非全日制时，报到证签发类别不能是 代理（托管）");
                }
            }

            // 毕业去向分类是考取或报送时 毕业去向等于升学
            if (!StudentSignConstants.LYFS_10.equals(dispatchHiredWay)) {
                studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_SX);
            }
        }

        validateStudentSign(studentSign);

        JsonResult dealHbIndustryResult = verifyDealHbIndustry(studentSign);
        if (Constants.RESULT_ERROR_CODE == dealHbIndustryResult.getCode()) {
            return dealHbIndustryResult;
        }

        String msg = "";
        // 赋值签约状态
        // 协议就业并且是网签 由studentSign提供签约状态
        // 否则其他就业方式签约状态按逻辑判断
        if (StudentSignConstants.SIGN_CATEGORY_XYJY.equals(studentSign.getSignCategory())
                && StudentSignConstants.SIGN_DEAL_CATEGORY_TRUE.equals(studentSign.getDealCategory())) {

        } else {
            // 灵活就业、自主创业、自由职业 签约状态为 已提交待上传协议备案表
            if (StudentSignConstants.SIGN_CATEGORY_LHJY.equals(studentSign.getSignCategory())
                    || StudentSignConstants.SIGN_CATEGORY_ZZCY.equals(studentSign.getSignCategory())
                    || StudentSignConstants.SIGN_CATEGORY_ZYZY.equals(studentSign.getSignCategory())) {
                studentSign.setSignState(StudentSignConstants.SIGN_STATE_STUDENT_SUBMIT_UPLOAD);
                msg = "，请上传所需图片";
            } else {
                // 升学、出国出境、待就业 签约状态为 已提交
                studentSign.setSignState(StudentSignConstants.SIGN_STATE_STUDENT_SUBMIT);
                msg = "，请等待审核";
            }
        }

        // 赋值默认派遣状态
        studentSign.setDispatchState(StudentSignConstants.DISPATCH_STATE_STUDENT_SUBMIT);

        // 设置扩展项、逻辑值
        setExt(studentSign, student);

        // 清除不必要的机构函
        clearCenterImg(studentSign);

        // 如果是空白协议不允许学生修改实际单位名称
        StudentSignBlank studentSignBlank = studentSignBlankMapper.selectById(studentSign.getBlankId());
        if (null != studentSignBlank) {
            studentSign.setDealCompanyName(studentSignBlank.getCompanyName());
        }

        // 基层就业标志 协议就业 更新实际单位名称
        if (StudentSignConstants.SIGN_CATEGORY_XYJY.equals(studentSign.getSignCategory())) {
            switch (studentSign.getBasicMark()) {
                case "三支一扶":
                    studentSign.setDealCompanyName(studentSign.getDealCompanyName() + "三支一扶");
                    break;
                case "西部计划":
                    studentSign.setDealCompanyName(studentSign.getDealCompanyName() + "西部计划");
                    break;
                case "应征入伍":
                    studentSign.setDealCompanyName(studentSign.getDealCompanyName() + "应征义务兵");
                    break;
            }
        }

        alterLog(old, studentSign, loginUserId, "3");

        // 表单规则验证
        JsonResult validateResult = validateRuleService.validate("student_sign", studentSign);
        if (Constants.RESULT_PAUSE_CODE == validateResult.getCode()) {
            return validateResult;
        }

        // 更新数据
        StudentSignlogUtil.log(logPath, studentSign, "学生提交保存前");
        if (baseMapper.updateById(studentSign) > 0) {
            // 记录到派遣信息
            studentSignDispatchService.saveByStudentSign(studentSign);
            // 记录操作
            studentRecordService.save(
                    new StudentRecord(loginUserId, studentSign.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, StudentConstants.RECORD_OPERATE_STUDENT_SIGN_SUBMIT)
            );
            // 关闭忽略系统单位自主录入
            studentService.changeSignEntry(student, loginUserId, StudentConstants.SIGN_ENTRY_FALSE);

            return JsonResult.ok("提交成功" + msg);
        }

        return JsonResult.error();
    }

    @Override
    public JsonResult submitRecord(StudentSign studentSign, Integer loginUserId) {
        if (studentSign == null) {
            throw new BusinessException("提交信息异常");
        }

        if (!loginUserId.equals(studentSign.getUserId())) {
            throw new BusinessException("学生毕业去向信息异常");
        }

        if (StudentSignConstants.SIGN_STATE_STUDENT_SUBMIT_UPLOAD.equals(studentSign.getSignState())) {
            studentSign.setSignState(StudentSignConstants.SIGN_STATE_STUDENT_SUBMIT);
        }

        if (StudentSignConstants.DISPATCH_STATE_EDIT_STUDENT_SUBMIT_UPLOAD.equals(studentSign.getDispatchState())) {
            studentSign.setDispatchState(StudentSignConstants.DISPATCH_STATE_EDIT_STUDENT_SUBMIT);
        }

        String img = studentSign.getRecordImg();
        String content = studentSign.getRecordContent();
        String signState = studentSign.getSignState();
        String dispatchState = studentSign.getDispatchState();
        boolean update = update(new LambdaUpdateWrapper<StudentSign>()
                .set(StudentSign::getRecordImg, img)
                .set(StudentSign::getRecordContent, content)
                .set(StudentSign::getSignState, signState)
                .set(StudentSign::getDispatchState, dispatchState)
                .eq(StudentSign::getId, studentSign.getId())
        );


        if (update) {
            // 记录操作
            studentRecordService.save(
                    new StudentRecord(loginUserId, studentSign.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, StudentConstants.RECORD_OPERATE_STUDENT_SIGN_UPLOAD)
            );

            return JsonResult.ok("上传成功，请等待审核");
        }

        return JsonResult.error();
    }

    @Override
    public PageResult<StudentSignAdminListVO> listAdminPage(PageParam<StudentSignAdminListVO> pageParam) {
        String category = pageParam.getString("category");
        String user = pageParam.getString("user");
        String categoryCode = "";
        pageParam.setOrder("ss.update_time", false);

        String signTimeStart = pageParam.getString("signTimeStart");
        String signTimeEnd = pageParam.getString("signTimeEnd");
        if (!StrUtil.isBlank(signTimeStart) && !StrUtil.isBlank(signTimeEnd)) {
            signTimeStart += " 00:00:00";
            signTimeEnd += " 23:59:59";
            pageParam.put("signTimeStart", signTimeStart);
            pageParam.put("signTimeEnd", signTimeEnd);
        }

        String alterTimeStart = pageParam.getString("alterTimeStart");
        String alterTimeEnd = pageParam.getString("alterTimeEnd");
        if (!StrUtil.isBlank(alterTimeStart) && !StrUtil.isBlank(alterTimeEnd)) {
            alterTimeStart += " 00:00:00";
            alterTimeEnd += " 23:59:59";
            pageParam.put("alterTimeStart", alterTimeStart);
            pageParam.put("alterTimeEnd", alterTimeEnd);
        }

        // 学院待审核
        if (StudentSignConstants.ADMIN_LIST_CATEGORY_1.equals(category) && "college".equals(user)) {
            categoryCode = "AND ((ss.sign_state = '2' OR ss.sign_state = '5' OR ss.sign_state = '10')";
            categoryCode += " OR ss.dispatch_state = '7')";
            categoryCode += " AND ss.sign_state != '12' AND ss.dispatch_state != '3' AND ss.dispatch_state != '9'";
            pageParam.setOrder("ss.update_time", true);
        }
        // 校级学院待审核
        if (StudentSignConstants.ADMIN_LIST_CATEGORY_7.equals(category)) {
            categoryCode = "AND ((ss.sign_state = '2' OR ss.sign_state = '5' OR ss.sign_state = '10')";
            categoryCode += " OR ss.dispatch_state = '7')";
            categoryCode += " AND ss.sign_state != '12' AND ss.dispatch_state != '3' AND ss.dispatch_state != '9'";
            pageParam.setOrder("ss.update_time", true);
        }
        // 学校待审核
        if (StudentSignConstants.ADMIN_LIST_CATEGORY_1.equals(category) && "school".equals(user)) {
            categoryCode = "AND (ss.sign_state = '11' OR ss.dispatch_state = '8')";
            pageParam.setOrder("ss.update_time", true);
        }
        if (StudentSignConstants.ADMIN_LIST_CATEGORY_2.equals(category)) {
            categoryCode = "AND ss.id IS NULL";
        }
        if (StudentSignConstants.ADMIN_LIST_CATEGORY_3.equals(category)) {
            categoryCode = "AND ss.sign_category != '10' AND ss.sign_state = '8' AND (ss.dispatch_state = '4' OR ss.dispatch_state = '10')";
        }
        if (StudentSignConstants.ADMIN_LIST_CATEGORY_4.equals(category)) {
            categoryCode = "AND ss.sign_category = '10' AND ss.sign_state = '8'";
        }
        if (StudentSignConstants.ADMIN_LIST_CATEGORY_5.equals(category)) {
            categoryCode = "AND ss.sign_category = '10' AND ss.sign_way = '1'";
            pageParam.put("categoryCode", categoryCode);
            return listAdminSignPage(pageParam);
        }
        if (StudentSignConstants.ADMIN_LIST_CATEGORY_6.equals(category)) {
            categoryCode = "AND ss.sign_state = '13'";
            pageParam.put("categoryCode", categoryCode);
            pageParam.setOrder("ss.sign_termination_time", false);
            return listAdminSignPage(pageParam);
        }
        // 院领导待审核
        if (StudentSignConstants.ADMIN_LIST_CATEGORY_8.equals(category)) {
            categoryCode = "AND ss.sign_state = '11'";
            pageParam.setOrder("ss.update_time", true);
        }
        pageParam.put("categoryCode", categoryCode);
        return new PageResult<>(baseMapper.listAdminPage(pageParam), pageParam.getTotal());
    }

    /**
     * 初始化一个毕业去向编号
     *
     * @return 毕业去向编号
     */
    @Override
    public String initSerialNumber() {
        // 编号长度
        int numberLength = 14;
        String dateStr = DateUtil.format(new Date(), "yyyyMMddHH");
        int excessLength = numberLength - dateStr.length();
        String random = RandomUtil.randomNumbers(excessLength);
        return dateStr + random;
    }

    /**
     * 邀约、解约记录
     * 从签约表出发，一个学生或多条数据
     *
     * @param pageParam PageParam<StudentSignAdminListVO>
     * @return PageResult<StudentSignAdminListVO>
     */
    private PageResult<StudentSignAdminListVO> listAdminSignPage(PageParam<StudentSignAdminListVO> pageParam) {
        return new PageResult<>(baseMapper.listAdminSignPage(pageParam), pageParam.getTotal());
    }

    /**
     * 非人才机构接收函上传要求录入方式
     * 清除人才机构接收函
     */
    private void clearCenterImg(StudentSign studentSign) {
        switch (studentSign.getDispatchHiredWay()) {
            case StudentSignConstants.LYFS_03:
            case StudentSignConstants.LYFS_08:
            case StudentSignConstants.LYFS_15:
            case StudentSignConstants.LYFS_22:
            case StudentSignConstants.LYFS_24:
                break;
            default:
                studentSign.setCenterImg("");
                break;
        }
    }

    @Override
    public JsonResult editForCollege(StudentSign studentSign, Integer loginUserId) {
        if (studentSign == null) {
            throw new BusinessException("提交信息异常");
        }
        String signState = studentSign.getSignState();

        Student student = studentService.getById(studentSign.getStudentId());

        if (student == null) {
            throw new BusinessException("学生信息异常");
        }

        StudentSign old = baseMapper.selectById(studentSign.getId());
        if (old == null) {
            throw new BusinessException("未查询到毕业去向信息");
        }

        studentSign.setCollegeUserId(loginUserId);

        // 设置扩展项、逻辑值
        setExt(studentSign, student);

        // 清除不必要的机构函
        clearCenterImg(studentSign);

        validateStudentSign(studentSign);

        // 表单规则验证
        JsonResult validateResult = validateRuleService.validate("student_sign", studentSign);
        if (Constants.RESULT_PAUSE_CODE == validateResult.getCode()) {
            return validateResult;
        }

        // 更新数据
        studentSign.setSignState(null);
        studentSign.setDispatchState(null);
        if (baseMapper.updateById(studentSign) > 0) {
            // 记录操作
            studentRecordService.save(
                    new StudentRecord(loginUserId, studentSign.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, StudentConstants.RECORD_OPERATE_COLLEGE_SIGN_EDIT, studentSign.getCollegeUserContent())
            );

            alterLog(old, studentSign, loginUserId, "2");

            // 审核通过
            if (StudentSignConstants.SIGN_STATE_SCHOOL_PASS.equals(signState)) {
                // 如果是关联空白协议 更新签约状态
                if (null != studentSign.getBlankId()) {
                    StudentSignBlank studentSignBlank = new StudentSignBlank();
                    studentSignBlank.setId(studentSign.getBlankId());
                    studentSignBlank.setSignState(StudentSignBlankConstants.SIGN_STATE_PASS);
                    studentSignBlankMapper.updateById(studentSignBlank);
                }

                // 录入奥兰
                StudentSignSet studentSignSet = studentSignSetService.get();
                // 开启同步
                if (0 == studentSignSet.getAoLan()) {
                    aoLanService.insert(studentSign);
                }
                // 关闭同步 如果奥兰无数据则同步
                if (0 != studentSignSet.getAoLan()) {
                    boolean b = aoLanService.verify(student.getYearId(), student.getXh());
                    if (!b) {
                        aoLanService.insert(studentSign);
                    }
                }

                // 更新就业状态
                if (StudentSignConstants.SIGN_CATEGORY_XYJY.equals(studentSign.getSignCategory())
                        || StudentSignConstants.SIGN_CATEGORY_LHJY.equals(studentSign.getSignCategory())) {
                    studentService.updateStatus(student.getId(), StudentConstants.SIGN_STATUS_SYS, "已签约", "");
                }
                if (StudentSignConstants.SIGN_CATEGORY_SX.equals(studentSign.getSignCategory())) {
                    studentService.updateStatus(student.getId(), StudentConstants.SIGN_STATUS_SYS, "升学(境内)", "");
                }
            }
            return JsonResult.ok();
        }

        return JsonResult.error();
    }

    @Override
    public JsonResult submitForCollege(StudentSign studentSign, Integer loginUserId) {
        StudentSignlogUtil.log(logPath, studentSign, "学院审核保存前");
        if (studentSign == null) {
            throw new BusinessException("提交信息异常");
        }

        StudentSign old = baseMapper.selectById(studentSign.getId());
        if (old == null) {
            throw new BusinessException("未查询到毕业去向信息");
        }

        Student student = studentService.getById(studentSign.getStudentId());

        if (student == null) {
            throw new BusinessException("学生信息异常");
        }

        validateStudentSign(studentSign);

        String operate = "";
        String emailContent = "";

        studentSign.setCollegeUserId(loginUserId);

        // 派遣不通过 学生状态为提交状态
        if (StudentSignConstants.DISPATCH_STATE_COLLEGE_FAIL.equals(studentSign.getDispatchState())) {
            studentSign.setSignState(StudentSignConstants.SIGN_STATE_STUDENT_SUBMIT);
            operate = "[学院审核派遣状态不通过]";
            emailContent = "派遣信息审核不通过，请登录系统修改后再提交审核";
        }

        // 派遣状态通过 默认学校通过
        if (StudentSignConstants.DISPATCH_STATE_COLLEGE_PASS.equals(studentSign.getDispatchState())) {
            studentSign.setDispatchState(StudentSignConstants.DISPATCH_STATE_SCHOOL_PASS);
            operate = "[学院审核派遣状态通过]";
        }

        // 签约状态通过 默认学校通过
        if (StudentSignConstants.SIGN_STATE_COLLEGE_PASS.equals(studentSign.getSignState())) {
            studentSign.setSignState(StudentSignConstants.SIGN_STATE_SCHOOL_PASS);
            if (studentSign.getSignTime() == null) {
                studentSign.setSignTime(new Date());
            }
            operate = "[学院审核签约状态通过]";
            emailContent = "签约(登记)审核通过";
        }

        // 辅导员 申请解约通过
        if (StudentSignConstants.SIGN_STATE_COLLEGE_TERMINATION_PASS.equals(studentSign.getSignState())) {
            studentSign.setSignState(StudentSignConstants.SIGN_STATE_COLLEGE_TERMINATION_PASS);
            studentSign.setMsgTitle("");
            studentSign.setMsgContent("");
            operate = "[辅导员解约审核通过]";
        }

        // 辅导员 申请解约不通过 回到已签约状态
        if (StudentSignConstants.SIGN_STATE_COLLEGE_TERMINATION_FAIL.equals(studentSign.getSignState())) {
            studentSign.setSignState(StudentSignConstants.SIGN_STATE_SCHOOL_PASS);
            studentSign.setMsgTitle("申请解约不通过，签约状态回到已签约");
            studentSign.setMsgContent(studentSign.getCollegeUserContent());
            operate = "[辅导员解约审核不通过，签约状态回到已签约]";
            emailContent = "申请解约审核未通过，登录系统查看原因";
        }

        // 院领导 申请解约通过
        if (StudentSignConstants.SIGN_STATE_COLLEGE_LEAD_TERMINATION_PASS.equals(studentSign.getSignState())) {
            studentSign.setSignState(StudentSignConstants.SIGN_STATE_COLLEGE_LEAD_TERMINATION_PASS);
            studentSign.setMsgTitle("");
            studentSign.setMsgContent("");
            operate = "[学院解约审核通过]";
        }

        // 院领导 申请解约不通过 回到已签约状态
        if (StudentSignConstants.SIGN_STATE_COLLEGE_LEAD_TERMINATION_FAIL.equals(studentSign.getSignState())) {
            studentSign.setSignState(StudentSignConstants.SIGN_STATE_SCHOOL_PASS);
            studentSign.setMsgTitle("申请解约不通过，签约状态回到已签约");
            studentSign.setMsgContent(studentSign.getCollegeUserContent());
            operate = "[院领导解约审核不通过，签约状态回到已签约]";
            emailContent = "申请解约审核未通过，登录系统查看原因";
        }

        // 申请改派院通过
        if (StudentSignConstants.DISPATCH_STATE_EDIT_COLLEGE_PASS.equals(studentSign.getDispatchState())) {
            studentSign.setDispatchState(StudentSignConstants.DISPATCH_STATE_EDIT_COLLEGE_PASS);
            studentSign.setMsgTitle("");
            studentSign.setMsgContent("");
            operate = "[学院审核改派通过]";
        }

        // 申请改派院不通过 改派申请状态回到已完成
        if (StudentSignConstants.DISPATCH_STATE_EDIT_COLLEGE_FAIL.equals(studentSign.getDispatchState())) {
            studentSign.setDispatchState(StudentSignConstants.DISPATCH_STATE_SCHOOL_PASS);
            studentSign = studentSignDispatchService.rollBack(studentSign);
            studentSign.setMsgTitle("申请改派不通过，派遣状态回到已完成");
            studentSign.setMsgContent(studentSign.getCollegeUserContent());
            operate = "[学院审核改派不通过]";
        }

        // 设置扩展项、逻辑值
        setExt(studentSign, student);

        // 清除不必要的机构函
        clearCenterImg(studentSign);

        // 表单规则验证
        JsonResult validateResult = validateRuleService.validate("student_sign", studentSign);
        if (Constants.RESULT_PAUSE_CODE == validateResult.getCode()) {
            return validateResult;
        }

        // 更新数据
        StudentSignlogUtil.log(logPath, studentSign, "学院审核保存时");
        if (baseMapper.updateById(studentSign) > 0) {
            // 记录操作
            studentRecordService.save(
                    new StudentRecord(loginUserId, studentSign.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, StudentConstants.RECORD_OPERATE_COLLEGE_SIGN_CHECK + "：" + operate, studentSign.getCollegeUserContent())
            );

            alterLog(old, studentSign, loginUserId, "2");

            // 审核通过
            if (StudentSignConstants.SIGN_STATE_SCHOOL_PASS.equals(studentSign.getSignState())) {
                // 如果是关联空白协议 更新签约状态
                if (null != studentSign.getBlankId()) {
                    StudentSignBlank studentSignBlank = new StudentSignBlank();
                    studentSignBlank.setId(studentSign.getBlankId());
                    studentSignBlank.setSignState(StudentSignBlankConstants.SIGN_STATE_PASS);
                    studentSignBlankMapper.updateById(studentSignBlank);
                }

                // 录入奥兰
                StudentSignSet studentSignSet = studentSignSetService.get();
                // 开启同步
                if (0 == studentSignSet.getAoLan()) {
                    aoLanService.insert(studentSign);
                }
                // 关闭同步 如果奥兰无数据则同步
                if (0 != studentSignSet.getAoLan()) {
                    boolean b = aoLanService.verify(student.getYearId(), student.getXh());
                    if (!b) {
                        aoLanService.insert(studentSign);
                    }
                }


                // 更新就业状态
                if (StudentSignConstants.SIGN_CATEGORY_XYJY.equals(studentSign.getSignCategory())
                        || StudentSignConstants.SIGN_CATEGORY_LHJY.equals(studentSign.getSignCategory())) {
                    studentService.updateStatus(student.getId(), StudentConstants.SIGN_STATUS_SYS, "已签约", "");
                }
                if (StudentSignConstants.SIGN_CATEGORY_SX.equals(studentSign.getSignCategory())) {
                    studentService.updateStatus(student.getId(), StudentConstants.SIGN_STATUS_SYS, "升学(境内)", "");
                }

            }
            // 发送邮件通知
            if (!StrUtil.isBlank(emailContent)) {
                emailService.sendTextEmail(EmailConstants.TITLE_SIGN, emailContent, new String[]{student.getEmail()});
            }
            return JsonResult.ok();
        }

        return JsonResult.error();
    }

    @Override
    public JsonResult submitForSchool(StudentSign studentSign, Integer loginUserId) {
        StudentSignlogUtil.log(logPath, studentSign, "学校审核保存前");
        if (studentSign == null) {
            throw new BusinessException("提交信息异常");
        }

        StudentSign old = baseMapper.selectById(studentSign.getId());
        if (old == null) {
            throw new BusinessException("未查询到毕业去向信息");
        }

        Student student = studentService.getById(studentSign.getStudentId());
        if (student == null) {
            throw new BusinessException("学生信息异常");
        }

        studentSign.setSchoolUserId(loginUserId);
        String operate = "";
        String emailContent = "";

        // 申请解约学校审核通过 重置就业方式
        if (StudentSignConstants.SIGN_STATE_SCHOOL_TERMINATION_PASS.equals(studentSign.getSignState())) {
            studentSign.setSignState(StudentSignConstants.SIGN_STATE_SCHOOL_TERMINATION_PASS);
            studentSign.setSignTerminationTime(new Date());
            studentSign.setState(StudentSignConstants.STATE_INVALID);
            studentSign.setMsgTitle("");
            studentSign.setMsgContent("");
            operate = "[学校审核解约审核通过,解约次数+1]";
            emailContent = "申请解约通过";
        }

        // 申请解约不通过 回到已签约状态
        if (StudentSignConstants.SIGN_STATE_SCHOOL_TERMINATION_FAIL.equals(studentSign.getSignState())) {
            studentSign.setSignState(StudentSignConstants.SIGN_STATE_SCHOOL_PASS);
            studentSign.setMsgTitle("申请解约不通过，签约状态回到已签约");
            studentSign.setMsgContent(studentSign.getSchoolUserContent());
            operate = "[学校审核解约审核不通过，签约状态回到已签约]";
            emailContent = "申请解约未通过，签约(登记)状态恢复至已签约，可以登录系统查看具体原因";
        }

        // 申请改派院通过
        if (StudentSignConstants.DISPATCH_STATE_EDIT_SCHOOL_PASS.equals(studentSign.getDispatchState())) {
            studentSign.setDispatchState(StudentSignConstants.DISPATCH_STATE_EDIT_SCHOOL_PASS);
            studentSign.setDispatch(studentSign.getDispatch() != null ? studentSign.getDispatch() + 1 : 1);
            studentSign.setDispatchTime(new Date());
            studentSign.setMsgTitle("");
            studentSign.setMsgContent("");
            operate = "[学校审核改派通过]";
            emailContent = "申请改派通过";
        }

        // 申请改派院不通过 改派申请状态回到已完成
        if (StudentSignConstants.DISPATCH_STATE_EDIT_COLLEGE_FAIL.equals(studentSign.getDispatchState())) {
            studentSign.setDispatchState(StudentSignConstants.DISPATCH_STATE_SCHOOL_PASS);
            studentSign = studentSignDispatchService.rollBack(studentSign);
            studentSign.setMsgTitle("申请改派不通过，派遣状态回到已完成");
            studentSign.setMsgContent(studentSign.getSchoolUserContent());
            operate = "[学校审核改派不通过]";
            emailContent = "申请改派未通过，改派信息状态恢复至已改派，可以登录系统查看具体原因";
        }

        // 设置扩展项、逻辑值
        setExt(studentSign, student);

        // 清除不必要的机构函
        clearCenterImg(studentSign);

        alterLog(old, studentSign, loginUserId, "1");

        // 更新数据
        StudentSignlogUtil.log(logPath, studentSign, "学校审核保存时");
        if (baseMapper.updateById(studentSign) > 0) {
            // 记录操作
            studentRecordService.save(
                    new StudentRecord(loginUserId, studentSign.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, !StrUtil.isBlank(operate) ? operate : StudentConstants.RECORD_OPERATE_SCHOOL_SIGN_UPDATE)
            );

            // 解约完成
            if (StudentSignConstants.SIGN_STATE_SCHOOL_TERMINATION_PASS.equals(studentSign.getSignState())) {
                // 解约次数+1 重置就业方式
                studentService.termination(student.getId());

                // 如果是关联空白协议 更新解约状态
                if (null != studentSign.getBlankId()) {
                    StudentSignBlank studentSignBlank = new StudentSignBlank();
                    studentSignBlank.setId(studentSign.getBlankId());
                    studentSignBlank.setSignState(StudentSignBlankConstants.SIGN_STATE_TERMINATION);
                    studentSignBlankMapper.updateById(studentSignBlank);
                }

                // 解约成功删除奥兰毕业去向信息
                aoLanService.delete(student.getYearId(), student.getXh());

                // 更新就业状态
                if (StudentSignConstants.SIGN_CATEGORY_XYJY.equals(studentSign.getSignCategory())
                        || StudentSignConstants.SIGN_CATEGORY_LHJY.equals(studentSign.getSignCategory())) {
                    studentService.updateStatus(student.getId(), StudentConstants.SIGN_STATUS_MANUAL, "", "");
                }
            }

            // 发送邮件通知
            if (!StrUtil.isBlank(emailContent)) {
                emailService.sendTextEmail(EmailConstants.TITLE_SIGN, emailContent, new String[]{student.getEmail()});
            }
            return JsonResult.ok();
        }

        return JsonResult.error();
    }

    @Override
    public JsonResult countAdmin(Map<String, Object> noPageParam) {
        StudentSignAdminCountVO countVO = new StudentSignAdminCountVO();
        countVO.setCountAll(baseMapper.countAdmin(noPageParam));

        String categoryCode = "AND ((ss.sign_state = '5' OR ss.sign_state = '10') AND (ss.dispatch_state = '1' OR ss.dispatch_state = '6'))";
        noPageParam.put("categoryCode", categoryCode);
        countVO.setCountWait(baseMapper.countAdmin(noPageParam));

        categoryCode = "AND ss.id IS NULL";
        noPageParam.put("categoryCode", categoryCode);
        countVO.setCountNot(baseMapper.countAdmin(noPageParam));

        categoryCode = "AND ss.sign_state != '5' AND ss.sign_state != '10' AND ss.dispatch_state != '1' AND ss.dispatch_state != '6'";
        noPageParam.put("categoryCode", categoryCode);
        countVO.setCountHas(baseMapper.countAdmin(noPageParam));

        return JsonResult.ok().setData(countVO);
    }

    @Override
    public PageResult<StudentSignCompanyListVO> listCompanyPage(PageParam<StudentSignCompanyListVO> pageParam) {
        Integer loginUserId = pageParam.getInt("loginUserId");
        if (loginUserId == null) {
            throw new BusinessException("登陆人信息异常");
        }

        Company company = companyService.getByUserId(loginUserId);
        if (company == null) {
            throw new BusinessException("单位信息异常");
        }
        pageParam.put("companyId", company.getId());

        String category = pageParam.getString("category");
        if (StudentSignConstants.COMPANY_LIST_CATEGORY_WAIT.equals(category)) {
            pageParam.put("signState", StudentSignConstants.SIGN_STATE_COMPANY_INVITED);
        }
        if (StudentSignConstants.COMPANY_LIST_CATEGORY_PROCESS.equals(category)) {
            pageParam.put("signState", StudentSignConstants.SIGN_STATE_STUDENT_AGREED);
        }
        if (StudentSignConstants.COMPANY_LIST_CATEGORY_REFUSED.equals(category)) {
            pageParam.put("signState", StudentSignConstants.SIGN_STATE_STUDENT_REFUSED);
        }
        if (StudentSignConstants.COMPANY_LIST_CATEGORY_TERMINATION.equals(category)) {
            pageParam.put("signState", StudentSignConstants.SIGN_STATE_SCHOOL_TERMINATION_PASS);
        }
        if (StudentSignConstants.COMPANY_LIST_CATEGORY_DEAL.equals(category)) {
            pageParam.put("signState", StudentSignConstants.SIGN_STATE_SCHOOL_PASS);
        }
        return new PageResult<>(baseMapper.listCompanyPage(pageParam), pageParam.getTotal());
    }

    @Override
    public JsonResult companySignForm(Integer loginUserId) {
        User user = userService.getById(loginUserId);
        if (user == null) {
            throw new BusinessException("单位用户信息异常");
        }

        Company company = companyService.getByUserId(loginUserId);
        if (company == null) {
            throw new BusinessException("单位信息异常");
        }

        JsonResult jsonResult = companyService.verifyCompanyState(company.getState());
        if (Constants.RESULT_ERROR_CODE == jsonResult.getCode()) {
            return jsonResult;
        }

        StudentSign studentSign = new StudentSign();
        studentSign.setCompanyId(company.getId());
        studentSign.setDealSignCompanyName(company.getName());
        studentSign.setDealCompanyOrganizationCode(company.getOrganizationCode());
        studentSign.setDealCompanyName(company.getName());
        studentSign.setDealCompanyAddress(company.getSyszd());
        studentSign.setDealCompanyAddressLevel(company.getCompanyLevel());
        studentSign.setDealCompanyNature(company.getNature());
        studentSign.setDealCompanyIndustry(company.getIndustry());
        studentSign.setDealCompanyContactName(company.getContactName());
        studentSign.setDealCompanyContactMobile(company.getContactMobile());
        studentSign.setDealCompanyContactZip(company.getZipCode());
        studentSign.setDealCompanyContactEmail(user.getUsername());
        studentSign.setDealCompanyContactAddress(company.getAddress());
        studentSign.setDealHbIndustry(!StrUtil.isBlank(company.getHbIndustry()) ? company.getHbIndustry() : "0");
        studentSign.setGoAbroad("1");

        // 如果单位地区是北京市、上海市、重庆市、天津市4个直辖市 则实际单位所在地设置为空
        if ("110000".equals(company.getSyszd()) || "120000".equals(company.getSyszd()) || "310000".equals(company.getSyszd()) || "500000".equals(company.getSyszd())) {
            studentSign.setDealCompanyAddress(null);
        }

        // 字典集合
        Map<String, List<Dict>> formMap = getFormMap();
        // 网签SYSZD字典移除北京市、上海市、重庆市、天津市4个直辖市
        List<Dict> syszdList = formMap.get(DictConstants.TYPE_SYSZD);
        List<Dict> removeSyszd = new ArrayList<>();
        for (Dict dict : syszdList) {
            if ("北京市".equals(dict.getLabel()) || "上海市".equals(dict.getLabel()) || "重庆市".equals(dict.getLabel()) || "天津市".equals(dict.getLabel())) {
                removeSyszd.add(dict);
                continue;
            }
        }
        syszdList.removeAll(removeSyszd);
        formMap.put(DictConstants.TYPE_SYSZD, syszdList);

        // 户口迁转类型 单位移除未迁入选项
        List<Dict> hkqzlxList = formMap.get(DictConstants.TYPE_HKQZLX);
        hkqzlxList.removeIf(dict -> "100".equals(dict.getValue()));
        formMap.put(DictConstants.TYPE_HKQZLX, hkqzlxList);

        return JsonResult.ok().setData(studentSign).put("dictMaps", formMap);
    }

    @Override
    public JsonResult companyPickDispatchHiredWay(StudentSign studentSign, Integer loginUserId) {
        Company company = companyService.getByUserId(loginUserId);

        if (company == null) {
            throw new BusinessException("单位信息异常");
        }

        if (studentSign == null) {
            throw new BusinessException("邀约数据异常");
        }

        String dispatchHiredWay = studentSign.getDispatchHiredWay();

        // 选择了空录用方式 提示不予选择
        if (StrUtil.isBlank(dispatchHiredWay)) {
            throw new BusinessException(Constants.RESULT_CONTINUE_CODE, "请选择其中一项录用方式");
        }

        dispatchClear(studentSign);

        if (StudentSignConstants.LYFS_06.equals(dispatchHiredWay)) {

        }

        if (StudentSignConstants.LYFS_02.equals(dispatchHiredWay)) {
            dispatchHiredWayHuBei(studentSign);
        }

        if (StudentSignConstants.LYFS_04.equals(dispatchHiredWay)) {

        }

        if (StudentSignConstants.LYFS_00.equals(dispatchHiredWay)) {

        }

        return JsonResult.ok().setData(studentSign);
    }

    @Override
    public JsonResult searchStudent(String xh, Integer loginUserId) {
        if (StrUtil.isBlank(xh)) {
            throw new ParameterException("学号不能为空");
        }

        Student student = studentService.getByXh(xh);

        // 验证学生信息
        if (student == null) {
            throw new BusinessException("没有查询到学生");
        }

        // 定向生未解锁不可邀约
        if (StudentConstants.PYFS_DX.equals(student.getPyfs())
                && StudentConstants.DIRECTIONAL_STATE_LOCK.equals(student.getDirectionalState())) {
            return JsonResult.error("该生为定向生，请先告知学生解锁成功后再进行邀约");
        }

        // 验证学生基础信息
        StudentInfo studentInfo = studentInfoService.getByStudentId(student.getId());
        if (studentInfo == null) {
            throw new BusinessException("学生基础信息异常");
        }

        // 验证单位信息
        Company company = companyService.getByUserId(loginUserId);
        if (company == null) {
            throw new BusinessException("单位信息异常");
        }

        // 验证当前单位与学生签约关系
        StudentSign studentSign = baseMapper.selectOne(new QueryWrapper<StudentSign>()
                .select("id, state, sign_state, sign_invited_time, sign_expired_time")
                .eq("student_id", student.getId())
                .eq("company_id", company.getId())
                .orderByDesc("id")
                .last("limit 1"));
        if (studentSign != null) {
            String state = studentSign.getState();
            String signState = studentSign.getSignState();

            if (!StudentSignConstants.SIGN_STATE_COMPANY_INVITED.equals(signState) && StudentSignConstants.STATE_INVALID.equals(state)) {
                // TODO: 2022/9/28 应约后状态且是无效的信息则可以再次邀约 这个IF直接跳过什么都不做
            } else {
                if (StudentSignConstants.SIGN_STATE_COMPANY_INVITED.equals(signState)) {
                    if (studentSign.getSignExpiredTime() != null) {
                        if (System.currentTimeMillis() < studentSign.getSignExpiredTime().getTime()) {
                            return JsonResult.error("已邀约该学生，请查看邀约记录");
                        }
                    }
                }
                if (StudentSignConstants.SIGN_STATE_STUDENT_AGREED.equals(signState)) {
                    return JsonResult.error("学生已应约，请等待审核");
                }
                if (StudentSignConstants.SIGN_STATE_COLLEGE_FAIL.equals(signState)) {
                    return JsonResult.error("审核不通过，不可邀约");
                }
                if (StudentSignConstants.SIGN_STATE_SCHOOL_PASS.equals(signState)) {
                    return JsonResult.error("已与该生签约");
                }
            }
        }

        JsonResult blankResult = blankVerify(student.getId());
        if (Constants.RESULT_ERROR_CODE == blankResult.getCode()) {
            return blankResult;
        }

        return JsonResult.ok().setData(student);
    }

    @Override
    public JsonResult submitForCompany(StudentSign studentSign, Integer loginUserId) {
        if (loginUserId == null) {
            throw new BusinessException("登录人信息异常");
        }

        Company company = companyService.getByUserId(loginUserId);

        if (company == null) {
            throw new BusinessException("单位信息异常");
        }

        if (studentSign == null) {
            throw new BusinessException("提交信息异常");
        }

        studentSign.setSignCategory(StudentSignConstants.SIGN_CATEGORY_XYJY);
        validateStudentSign(studentSign);

        JsonResult dealHbIndustryResult = verifyDealHbIndustry(studentSign);
        if (Constants.RESULT_ERROR_CODE == dealHbIndustryResult.getCode()) {
            return dealHbIndustryResult;
        }

        // 如果是单位填写户口迁转地址 赋值值到户口迁移地址上
        if (StudentSignConstants.DISPATCH_HK_ADDRESS_WHO_COMPANY.equals(studentSign.getDispatchHkAddressWho())) {
            studentSign.setDispatchHkAddress(studentSign.getHkqzdz());
        }

        // 修改
        if (studentSign.getId() != null) {
            // 学生应约情况下修改 将修改内容新增为一个新的无效协议内容 内容标识为修改版
            if (!StudentSignConstants.SIGN_STATE_COMPANY_INVITED.equals(studentSign.getSignState())) {
                StudentSignEdit insert = new StudentSignEdit();
                BeanUtil.copyProperties(studentSign, insert);
                insert.setStudentSignId(studentSign.getId());
                studentSignEditService.save(insert);
                studentRecordService.save(
                        new StudentRecord(loginUserId, studentSign.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, StudentConstants.RECORD_OPERATE_COMPANY_SIGN_UPDATE_YY)
                );
                return JsonResult.ok("修改成功,等待学生确认");
            }

            studentSign.setState(StudentSignConstants.STATE_INVALID);
            studentSign.setSignState(StudentSignConstants.SIGN_STATE_COMPANY_INVITED);
            studentSign.setDispatchState(StudentSignConstants.DISPATCH_STATE_STUDENT_WAIT);
            if (baseMapper.updateById(studentSign) > 0) {
                studentRecordService.save(
                        new StudentRecord(loginUserId, studentSign.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, StudentConstants.RECORD_OPERATE_COMPANY_SIGN_UPDATE)
                );
                return JsonResult.ok("修改成功");
            }
            return JsonResult.error("修改失败");
        }

        // 邀约
        if (CollectionUtil.isEmpty(studentSign.getStudentIdList())) {
            throw new BusinessException("请确认邀约名单中是否邀约了学生");
        }

        int success = 0;
        int failed = 0;

        StudentSignSet studentSignSet = studentSignSetService.get();
        if (studentSignSet == null) {
            throw new BusinessException("签约设置异常，请联系管理员");
        }
        // 邀约时间
        Date signInvitedTime = new Date();
        // 邀约过期时间 在邀约时间的基础上偏移'签约设置中的邀约失效天数'
        Date signExpiredTime = DateUtil.offsetDay(signInvitedTime, studentSignSet.getAgreedFailureDay());

        studentSign.setState(StudentSignConstants.STATE_INVALID);
        studentSign.setSignState(StudentSignConstants.SIGN_STATE_COMPANY_INVITED);
        studentSign.setDispatchState(StudentSignConstants.DISPATCH_STATE_STUDENT_WAIT);
        studentSign.setSignWay(StudentSignConstants.SIGN_WAY_COMPANY);
        studentSign.setDealCategory(StudentSignConstants.SIGN_DEAL_CATEGORY_TRUE);
        for (int studentId : studentSign.getStudentIdList()) {
            Student student = studentService.getById(studentId);
            if (student == null) {
                failed++;
                continue;
            }

            studentSign.setStudentId(studentId);
            studentSign.setUserId(student.getUserId());
            studentSign.setCompanyId(company.getId());
            studentSign.setSignInvitedTime(signInvitedTime);
            studentSign.setSignExpiredTime(signExpiredTime);

            StudentSignlogUtil.log(logPath, studentSign, "单位邀约");
            if (baseMapper.insert(studentSign) > 0) {
                studentSignDispatchService.saveByStudentSign(studentSign);
                studentRecordService.save(
                        new StudentRecord(loginUserId, studentSign.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, StudentConstants.RECORD_OPERATE_COMPANY_SIGN_INVITATION)
                );
                emailService.sendTextEmail(EmailConstants.TITLE_SIGN_COMPANY_INVITED, company.getName() + " 向您发送了签约申请，登录就业网查看", new String[]{student.getEmail()});
                success++;
            } else {
                failed++;
            }
        }

        if (studentSign.getStudentIdList().size() == success) {
            return JsonResult.ok("邀约成功");
        }

        if (studentSign.getStudentIdList().size() == failed) {
            return JsonResult.error("邀约失败");
        }

        return JsonResult.ok("邀约成功" + success + "个，失败" + failed + "个");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult agreedSign(StudentSign studentSign, Integer loginUserId) {
        if (studentSign == null) {
            throw new ParameterException("签约参数异常");
        }

        Student student = studentService.getByUserId(loginUserId);
        if (student == null) {
            throw new BusinessException("学生信息异常");
        }

        if (!StudentConstants.STUDENT_SCHOOL_PASS.equals(student.getSchoolState())) {
            throw new BusinessException("请先完成生源并等待学校审核通过");
        }

        if (!student.getId().equals(studentSign.getStudentId())) {
            throw new BusinessException("签约信息不匹配");
        }

        validateStudentSign(studentSign);

        JsonResult blankResult = blankVerify(student.getId());
        if (Constants.RESULT_ERROR_CODE == blankResult.getCode()) {
            return blankResult;
        }

        JsonResult expired = verifySignExpiredTime(studentSign);
        if (Constants.RESULT_ERROR_CODE == expired.getCode()) {
            return expired;
        }

        List<StudentSign> list = baseMapper.selectList(new QueryWrapper<StudentSign>()
                .eq("student_id", student.getId())
                .eq("state", StudentSignConstants.STATE_VALID)
        );
        if (list != null && list.size() > 0) {
            if (list.get(0).getId().equals(studentSign.getId())) {
                return JsonResult.error("已应约当前信息");
            }
            return JsonResult.error("已选择了一种就业方式，请重置就业方式后再进行应约");
        }

        JsonResult jsonResult = terminationFrozenDay(loginUserId);
        if (Constants.RESULT_ERROR_CODE == jsonResult.getCode()) {
            return jsonResult;
        }

        boolean studentUpdate = studentService.updateSignCategory("10", studentSign.getStudentId());
        if (!studentUpdate) {
            throw new BusinessException("应约失败，更新学生状态异常");
        }

        setExt(studentSign, student);

        studentSign.setSerialNumber(initSerialNumber());
        studentSign.setSignState(StudentSignConstants.SIGN_STATE_STUDENT_AGREED);
        studentSign.setDispatchState(StudentSignConstants.DISPATCH_STATE_STUDENT_SUBMIT);
        studentSign.setSignAgreedTime(new Date());
        studentSign.setState(StudentSignConstants.STATE_VALID);
        if (baseMapper.updateById(studentSign) > 0) {
            studentRecordService.save(
                    new StudentRecord(loginUserId, studentSign.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, StudentConstants.RECORD_OPERATE_STUDENT_SIGN_AGREED)
            );
            // 关闭忽略系统单位自主录入
            studentService.changeSignEntry(student, loginUserId, StudentConstants.SIGN_ENTRY_FALSE);
            return JsonResult.ok("应约成功");
        }

        throw new BusinessException("应约失败，更新签约信息异常");
    }

    @Override
    public JsonResult termination(StudentSign studentSign, Integer loginUserId) {
        Student student = studentService.getByUserId(loginUserId);
        if (student == null) {
            throw new BusinessException("学生信息异常");
        }

        StudentSignSet studentSignSet = studentSignSetService.get();
        if (studentSignSet == null) {
            throw new BusinessException("签约设置异常，请联系管理员");
        }

        Year year = yearService.getYear();
        if (year == null) {
            throw new BusinessException("毕业年份异常");
        }

        // 应届毕业生验证解约次数
        if (student.getYearId() >= year.getId()) {
            if (StudentConstants.FREE_TERMINATION_CLOSE.equals(student.getFreeTermination())) {
                if (student.getTermination() >= studentSignSet.getTermination()) {
                    throw new BusinessException("解约次数已超过规定次数(" + studentSignSet.getTermination() + "次)，不能解约");
                }
            }
        }

        StudentSign ss = getStateValid(loginUserId);
        if (ss == null) {
            throw new BusinessException("没有找到签约信息");
        }

        if (!StudentSignConstants.SIGN_STATE_SCHOOL_PASS.equals(ss.getSignState())) {
            throw new BusinessException("签约状态必须是'已签约'");
        }

        if (!StudentSignConstants.DISPATCH_STATE_SCHOOL_PASS.equals(ss.getDispatchState())
                && !StudentSignConstants.DISPATCH_STATE_EDIT_SCHOOL_PASS.equals(ss.getDispatchState())
        ) {
            throw new BusinessException("派遣状态必须是'已派遣或已改派'");
        }

        ss.setSignState(StudentSignConstants.SIGN_STATE_STUDENT_TERMINATION);
        ss.setTerminationTitle(studentSign.getTerminationTitle());
        ss.setTerminationContent(studentSign.getTerminationContent());
        ss.setTerminationImg(studentSign.getTerminationImg());
        ss.setTerminationTime(new Date());
        if (baseMapper.updateById(ss) > 0) {
            studentRecordService.save(
                    new StudentRecord(loginUserId, ss.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, StudentConstants.RECORD_OPERATE_STUDENT_SIGN_TERMINATION)
            );

            // 申请解约成功 关闭自由解约
            if (StudentConstants.FREE_TERMINATION_OPEN.equals(student.getFreeTermination())) {
                Student update = new Student();
                update.setId(student.getId());
                update.setFreeTermination(StudentConstants.FREE_TERMINATION_CLOSE);
                studentService.updateById(update);
                studentRecordService.save(
                        new StudentRecord(loginUserId, ss.getStudentId(), StudentConstants.RECORD_TYPE_STUDENT, "学生申请解约自动关闭自由解约")
                );
            }

            return JsonResult.ok("申请解约成功，请等待后续审核");
        }

        return JsonResult.error("申请解约失败");
    }

    @Override
    public JsonResult terminationFrozenDay(Integer loginUserId) {
//        StudentSignSet studentSignSet = studentSignSetService.get();
//        if (studentSignSet == null || studentSignSet.getTerminationFrozenDay() == null) {
//            return JsonResult.ok();
//        }
//
//        StudentSign studentSign = baseMapper.selectOne(new QueryWrapper<StudentSign>()
//                .select("sign_termination_time")
//                .eq("user_id", loginUserId)
//                .eq("sign_state", StudentSignConstants.SIGN_STATE_SCHOOL_TERMINATION_PASS)
//                .orderByDesc("sign_termination_time")
//                .last("limit 1")
//        );
//
//        if (studentSign == null || studentSign.getSignTerminationTime() == null) {
//            return JsonResult.ok();
//        }
//
//        long betweenDay = DateUtil.between(studentSign.getSignTerminationTime(), new Date(), DateUnit.DAY);
//        if (studentSignSet.getTerminationFrozenDay() > betweenDay) {
//            return JsonResult.error().setMsg(
//                    "最近一次解约时间为：" + DateUtil.format(studentSign.getSignTerminationTime(), DatePattern.NORM_DATETIME_MINUTE_PATTERN) +
//                            "，解约再签约解冻时间为解约成功后的" + studentSignSet.getTerminationFrozenDay() + "天。还有" + betweenDay + "天才可再签约"
//            );
//        }

        return JsonResult.ok();
    }

    @Override
    public JsonResult dispatch(StudentSign studentSign) {
        if (studentSign == null) {
            throw new BusinessException("信息异常");
        }

        if (!StudentSignConstants.SIGN_STATE_SCHOOL_PASS.equals(studentSign.getSignState())) {
            throw new BusinessException("签约状态必须是已签约才可以申请改派");
        }

        if (!StudentSignConstants.DISPATCH_STATE_SCHOOL_PASS.equals(studentSign.getDispatchState()) &&
                !StudentSignConstants.DISPATCH_STATE_EDIT_SCHOOL_PASS.equals(studentSign.getDispatchState())
        ) {
            throw new BusinessException("派遣状态必须是已派遣或已改派才可以申请(再次)改派");
        } else {
            studentSignDispatchService.saveByStudentSign(studentSign);

            clearCenterImg(studentSign);

            String msg = "";
            // 协议就业、灵活就业、自主创业、自由职业 签约状态为 改派已提交待上传协议备案表
            if (StudentSignConstants.SIGN_CATEGORY_XYJY.equals(studentSign.getSignCategory())
                    || StudentSignConstants.SIGN_CATEGORY_LHJY.equals(studentSign.getSignCategory())
                    || StudentSignConstants.SIGN_CATEGORY_ZZCY.equals(studentSign.getSignCategory())
                    || StudentSignConstants.SIGN_CATEGORY_ZYZY.equals(studentSign.getSignCategory())) {
                studentSign.setDispatchState(StudentSignConstants.DISPATCH_STATE_EDIT_STUDENT_SUBMIT_UPLOAD);
                msg = "请重新上传所需图片";
            } else {
                // 升学、出国出境、待就业 签约状态为 改派已提交
                studentSign.setDispatchState(StudentSignConstants.DISPATCH_STATE_EDIT_STUDENT_SUBMIT);
                msg = "请等待审核";
            }

            baseMapper.updateById(studentSign);

            return JsonResult.ok("申请改派成功，" + msg);
        }

    }

    @Override
    public void closeMsg(Integer studentSignId) {
        StudentSign studentSign = new StudentSign();
        studentSign.setId(studentSignId);
        studentSign.setMsgTitle("");
        studentSign.setMsgContent("");
        baseMapper.updateById(studentSign);
    }

    @Override
    public void exportStudentSign(PageParam<StudentSignAdminListVO> pageParam, HttpServletResponse response) {
        List<StudentSignExcelVO> list = new ArrayList<>();

        String category = pageParam.getString("category");
        String user = pageParam.getString("user");
        String categoryCode = "";
        pageParam.setOrder("ss.update_time", false);
        pageParam.setSize(50000);

        String signTimeStart = pageParam.getString("signTimeStart");
        String signTimeEnd = pageParam.getString("signTimeEnd");
        if (!StrUtil.isBlank(signTimeStart) && !StrUtil.isBlank(signTimeEnd)) {
            signTimeStart += " 00:00:00";
            signTimeEnd += " 23:59:59";
            pageParam.put("signTimeStart", signTimeStart);
            pageParam.put("signTimeEnd", signTimeEnd);
        }

        TimeInterval timer = DateUtil.timer();

        if (StudentSignConstants.ADMIN_LIST_CATEGORY_1.equals(category) && "college".equals(user)) {
            categoryCode = "AND ((ss.sign_state = '2' OR ss.sign_state = '5' OR ss.sign_state = '10')";
            categoryCode += " OR ss.dispatch_state = '7')";
            categoryCode += " AND ss.sign_state != '12' AND ss.dispatch_state != '3' AND ss.dispatch_state != '9'";
            pageParam.put("categoryCode", categoryCode);
            pageParam.setOrder("ss.update_time", true);
            list = baseMapper.listAdminExcelList(pageParam);
        } else if (StudentSignConstants.ADMIN_LIST_CATEGORY_7.equals(category)) {
            categoryCode = "AND ((ss.sign_state = '2' OR ss.sign_state = '5' OR ss.sign_state = '10')";
            categoryCode += " OR ss.dispatch_state = '7')";
            categoryCode += " AND ss.sign_state != '12' AND ss.dispatch_state != '3' AND ss.dispatch_state != '9'";
            pageParam.setOrder("ss.update_time", true);
            pageParam.put("categoryCode", categoryCode);
            list = baseMapper.listAdminExcelList(pageParam);
        } else if (StudentSignConstants.ADMIN_LIST_CATEGORY_1.equals(category) && "school".equals(user)) {
            categoryCode = "AND (ss.sign_state = '11' OR ss.dispatch_state = '8')";
            pageParam.setOrder("ss.update_time", true);
            list = baseMapper.listAdminExcelList(pageParam);
        } else if (StudentSignConstants.ADMIN_LIST_CATEGORY_2.equals(category)) {
            categoryCode = "AND ss.id IS NULL";
            pageParam.put("categoryCode", categoryCode);
            list = baseMapper.listAdminExcelList(pageParam);
        } else if (StudentSignConstants.ADMIN_LIST_CATEGORY_3.equals(category)) {
            categoryCode = "AND ss.sign_category != '10' AND ss.sign_state = '8' AND (ss.dispatch_state = '4' OR ss.dispatch_state = '10')";
            pageParam.put("categoryCode", categoryCode);
            list = baseMapper.listAdminExcelList(pageParam);
        } else if (StudentSignConstants.ADMIN_LIST_CATEGORY_4.equals(category)) {
            categoryCode = "AND ss.sign_category = '10' AND ss.sign_state = '8'";
            pageParam.put("categoryCode", categoryCode);
            list = baseMapper.listAdminExcelList(pageParam);
        } else if (StudentSignConstants.ADMIN_LIST_CATEGORY_5.equals(category)) {
            categoryCode = "AND ss.sign_category = '10' AND ss.sign_way = '1'";
            pageParam.put("categoryCode", categoryCode);
            list = baseMapper.listAdminSignExcelList(pageParam);
        } else if (StudentSignConstants.ADMIN_LIST_CATEGORY_6.equals(category)) {
            categoryCode = "AND ss.sign_state = '13'";
            pageParam.put("categoryCode", categoryCode);
            list = baseMapper.listAdminSignExcelList(pageParam);
        } else {
            list = baseMapper.listAdminExcelList(pageParam);
        }

        Map<Object, Object> dictMap = dictService.getCacheDictMaps();
        for (StudentSignExcelVO vo : list) {
            vo.setPyfs(dictService.cacheLabel(DictConstants.TYPE_PYFS, vo.getPyfs(), dictMap));
            vo.setSignCategory(dictService.cacheLabel(DictConstants.TYPE_SIGN_CATEGORY, vo.getSignCategory(), dictMap));
            vo.setDispatchHiredWay(dictService.cacheLabel(DictConstants.TYPE_SIGN_LYFS, vo.getDispatchHiredWay(), dictMap));
            vo.setDispatchGradWhere(dictService.cacheLabel(DictConstants.TYPE_SIGN_BYQX, vo.getDispatchGradWhere(), dictMap));
            vo.setDispatchReportIssuedCategory(dictService.cacheLabel(DictConstants.TYPE_SIGN_BDZQFLB, vo.getDispatchReportIssuedCategory(), dictMap));
            vo.setDispatchCompanyMembership(dictService.cacheLabel(DictConstants.TYPE_SIGN_DWLS, vo.getDispatchCompanyMembership(), dictMap));
            vo.setDispatchReportCompanyAddress(dictService.cacheLabel(DictConstants.TYPE_SYSZD, vo.getDispatchReportCompanyAddress(), dictMap));
            vo.setDealCompanyNature(dictService.cacheLabel(DictConstants.COMPANY_NATURE, vo.getDealCompanyNature(), dictMap));
            vo.setDispatchJobCondition(dictService.cacheLabel(DictConstants.TYPE_SIGN_JYZK, vo.getDispatchJobCondition(), dictMap));
            vo.setDispatchJobCategory(dictService.cacheLabel(DictConstants.TYPE_SIGN_JYLB, vo.getDispatchJobCategory(), dictMap));
            vo.setWaitCategory(dictService.cacheLabel(DictConstants.TYPE_SIGN_WAIT_CATEGORY, vo.getWaitCategory(), dictMap));
            vo.setDealCompanyIndustry(dictService.cacheLabel(DictConstants.COMPANY_INDUSTRY, vo.getDealCompanyIndustry(), dictMap));
            vo.setDealCompanyAddress(dictService.cacheLabel(DictConstants.TYPE_SYSZD, vo.getDealCompanyAddress(), dictMap));
            vo.setDealCompanyAddressLevel(dictService.cacheLabel(DictConstants.TYPE_SIGN_DWSZDJB, vo.getDealCompanyAddressLevel(), dictMap));
            vo.setDealHbIndustry(dictService.cacheLabel(DictConstants.TYPE_SIGN_HBZDCY, vo.getDealHbIndustry(), dictMap));
            vo.setDealWorkJobCategory(dictService.cacheLabel(DictConstants.TYPE_SIGN_GZZWLB, vo.getDealWorkJobCategory(), dictMap));
            vo.setSurveySalary(dictService.cacheLabel(DictConstants.TYPE_SIGN_YXDJ, vo.getSurveySalary(), dictMap));
            vo.setSurveyWay(dictService.cacheLabel(DictConstants.TYPE_SIGN_XQTJ, vo.getSurveyWay(), dictMap));
            vo.setSurveyCompany(dictService.cacheLabel(DictConstants.TYPE_SIGN_MYCD, vo.getSurveyCompany(), dictMap));
            vo.setSurveyJob(dictService.cacheLabel(DictConstants.TYPE_SIGN_XGCD, vo.getSurveyJob(), dictMap));
            vo.setSurveyMatching(dictService.cacheLabel(DictConstants.TYPE_SIGN_RZPP, vo.getSurveyMatching(), dictMap));
            vo.setSurveyOffer(dictService.cacheLabel(DictConstants.TYPE_SIGN_OFFER, vo.getSurveyOffer(), dictMap));
            vo.setSurveySchool(dictService.cacheLabel(DictConstants.TYPE_SIGN_MYD, vo.getSurveySchool(), dictMap));
            vo.setSignWay(dictService.cacheLabel(DictConstants.TYPE_SIGN_WAY, vo.getSignWay(), dictMap));
            vo.setConfirmState(StudentSignConstants.CONFIRM_TRUE.equals(vo.getConfirmState()) ? "已确认" : "未确认");
            vo.setAlterState(StudentSignConstants.ALTER_TRUE.equals(vo.getAlterState()) ? "变动" : "未变动");
            vo.setDispatchArchivesCategory(dictService.cacheLabel(DictConstants.DISPATCH_ARCHIVES_CATEGORY, vo.getDispatchArchivesCategory(), dictMap));
            vo.setHkqzlx(dictService.cacheLabel(DictConstants.TYPE_HKQZLX, vo.getHkqzlx(), dictMap));
            vo.setHkqzszd(dictService.cacheLabel(DictConstants.TYPE_SYSZD, vo.getHkqzszd(), dictMap));

            String abroadType = "";
            if ("1".equals(vo.getAbroadType())) {
                abroadType = "留学";
            }
            if ("2".equals(vo.getAbroadType())) {
                abroadType = "工作";
            }
            vo.setAbroadType(abroadType);
            vo.setAbroadDegree(dictService.cacheLabel(DictConstants.ABROAD_DEGREE, vo.getAbroadDegree(), dictMap));

            // 单位代码
            String dwdm = vo.getDispatchCompanyCode();
            if (!StrUtil.isBlank(dwdm)) {
                if (dwdm.length() == 2) {
                    dwdm = "00" + dwdm;
                    vo.setDispatchCompanyCode(dwdm);
                }
                if (dwdm.length() == 3) {
                    dwdm = "0" + dwdm;
                    vo.setDispatchCompanyCode(dwdm);
                }
            }

            if ("自由职业".equals(vo.getSignCategory())) {
                vo.setDealCompanyAddress(dictService.cacheLabel(DictConstants.TYPE_SYSZD, vo.getFreeWorkAddress(), dictMap));
            }

            vo.setSignState(dictService.cacheLabel(DictConstants.TYPE_SIGN_STATE, vo.getSignState(), dictMap));
            vo.setGoAbroad("0".equals(vo.getGoAbroad()) ? "是" : "否");
        }

        System.out.println("导出 数据转换耗时：" + timer.interval() + " 毫秒");

        // 导出excel模板
        ExcelWriter writer = ExcelUtil.getWriter(true);

        // 设置别名和排序
        excelAddHeaderAlias(writer);

        // 写出内容 xlsx
        writer.write(list, true);

        // 设置列自适应宽 必须在write以后
        ExcelUtils.autoColumnMaxSizeAll(writer.getSheet());

        String fileName = "student-sign-" + DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN) + ".xlsx";

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

        try {
            OutputStream out = response.getOutputStream();
            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
        } catch (IOException e) {
            writer.close();
            logger.error("导出失败 - StudentSignServiceImpl - exportStudentSign", e);
        } finally {
            writer.close();
        }
    }

    @Override
    public JsonResult dealPrint(Integer id, Integer loginUserId) {
        if (id == null && loginUserId == null) {
            throw new BusinessException("参数异常");
        }

        DealPrintVO dealPrintVO = new DealPrintVO();
        dealPrintVO.setId(id);
        dealPrintVO.setUserId(loginUserId);
        dealPrintVO.setSignCategory(StudentSignConstants.SIGN_CATEGORY_XYJY);
        dealPrintVO.setDeleted(Constants.DELETED_TRUE);
        if (id == null) {
            dealPrintVO.setState(StudentSignConstants.STATE_VALID);
        }

        DealPrintVO data = baseMapper.dealPrint(dealPrintVO);
        if (data == null) {
            throw new BusinessException("数据异常");
        }

        data.setTitle("中南财经政法大学毕业生就业协议备案表(" + data.getYearId() + " 届 )");
        String printState = printState(data.getSignState(), data.getDispatchState());
        printState = StudentSignConstants.STATE_VALID.equals(data.getState()) ? printState : StudentSignConstants.STATE_INVALID;
        data.setPrintState(printState);

        data.setXb(dictService.cacheLabel(DictConstants.TYPE_XB, data.getXb()));
        data.setZzmm(dictService.cacheLabel(DictConstants.TYPE_ZZMM, data.getZzmm()));
        data.setXl(dictService.cacheLabel(DictConstants.TYPE_XL, data.getXl()));
        data.setSyszd(dictService.cacheLabel(DictConstants.TYPE_SYSZD, data.getSyszd()));

        // 2025届及以上的毕业生户口迁移地址改为户口迁转地址
        if (data.getYearId() >= 2025) {
            data.setDispatchHkAddress(data.getHkqzdz());
        }

        return JsonResult.ok().setData(data);
    }

    @Override
    public JsonResult agilePrint(Integer id, Integer loginUserId) {
        if (id == null && loginUserId == null) {
            throw new BusinessException("参数异常");
        }

        AgilePrintVO agilePrintVO = new AgilePrintVO();
        agilePrintVO.setId(id);
        agilePrintVO.setUserId(loginUserId);
        agilePrintVO.setSignCategory(StudentSignConstants.SIGN_CATEGORY_LHJY);
        agilePrintVO.setDeleted(Constants.DELETED_TRUE);
        if (id == null) {
            agilePrintVO.setState(StudentSignConstants.STATE_VALID);
        }

        AgilePrintVO data = baseMapper.agilePrint(agilePrintVO);
        if (data == null) {
            throw new BusinessException("数据异常");
        }

        data.setTitle("毕业生就业证明");
        String printState = printState(data.getSignState(), data.getDispatchState());
        printState = StudentSignConstants.STATE_VALID.equals(data.getState()) ? printState : StudentSignConstants.STATE_INVALID;
        data.setPrintState(printState);

        String agilePositionTime = data.getAgilePositionTime();
        if (!StrUtil.isBlank(agilePositionTime)) {
            Date positionTime = DateUtil.parse(agilePositionTime);
            data.setAgilePositionTimeYear(DateUtil.format(positionTime, "yyyy"));
            data.setAgilePositionTimeMonth(DateUtil.format(positionTime, "MM"));
            data.setAgilePositionTimeDay(DateUtil.format(positionTime, "dd"));
        }

        String agileTermTime = data.getAgileTermTime();
        if (!StrUtil.isBlank(agileTermTime)) {
            Date termTime = DateUtil.parse(agileTermTime);
            data.setAgileTermTimeYear(DateUtil.format(termTime, "yyyy"));
            data.setAgileTermTimeMonth(DateUtil.format(termTime, "MM"));
            data.setAgileTermTimeDay(DateUtil.format(termTime, "dd"));
        }

        data.setXb(dictService.cacheLabel(DictConstants.TYPE_XB, data.getXb()));
        data.setXl(dictService.cacheLabel(DictConstants.TYPE_XL, data.getXl()));
        data.setDealCompanyNature(dictService.cacheLabel(DictConstants.COMPANY_NATURE, data.getDealCompanyNature()));
        data.setDealCompanyIndustry(dictService.cacheLabel(DictConstants.COMPANY_INDUSTRY, data.getDealCompanyIndustry()));
        data.setDealWorkJobCategory(dictService.cacheLabel(DictConstants.TYPE_SIGN_GZZWLB, data.getDealWorkJobCategory()));

        return JsonResult.ok().setData(data);
    }

    @Override
    public JsonResult freePrint(Integer id, Integer loginUserId) {
        if (id == null && loginUserId == null) {
            throw new BusinessException("参数异常");
        }

        FreePrintVO freePrintVO = new FreePrintVO();
        freePrintVO.setId(id);
        freePrintVO.setUserId(loginUserId);
        freePrintVO.setSignCategory(StudentSignConstants.SIGN_CATEGORY_ZYZY);
        freePrintVO.setDeleted(Constants.DELETED_TRUE);
        if (id == null) {
            freePrintVO.setState(StudentSignConstants.STATE_VALID);
        }

        FreePrintVO data = baseMapper.freePrint(freePrintVO);
        if (data == null) {
            throw new BusinessException("数据异常");
        }

        data.setTitle("普通高校毕业生自由职业登记表");
        String printState = printState(data.getSignState(), data.getDispatchState());
        printState = StudentSignConstants.STATE_VALID.equals(data.getState()) ? printState : StudentSignConstants.STATE_INVALID;
        data.setPrintState(printState);

        data.setXb(dictService.cacheLabel(DictConstants.TYPE_XB, data.getXb()));
        data.setXl(dictService.cacheLabel(DictConstants.TYPE_XL, data.getXl()));
        data.setSyszd(dictService.cacheLabel(DictConstants.TYPE_SYSZD, data.getSyszd()));
        data.setFreeWorkAddress(dictService.cacheLabel(DictConstants.TYPE_SYSZD, data.getFreeWorkAddress()));

        return JsonResult.ok().setData(data);
    }

    @Override
    public JsonResult venturePrint(Integer id, Integer loginUserId) {
        if (id == null && loginUserId == null) {
            throw new BusinessException("参数异常");
        }

        VenturePrintVO venturePrintVO = new VenturePrintVO();
        venturePrintVO.setId(id);
        venturePrintVO.setUserId(loginUserId);
        venturePrintVO.setSignCategory(StudentSignConstants.SIGN_CATEGORY_ZZCY);
        venturePrintVO.setDeleted(Constants.DELETED_TRUE);
        if (id == null) {
            venturePrintVO.setState(StudentSignConstants.STATE_VALID);
        }

        VenturePrintVO data = baseMapper.venturePrint(venturePrintVO);
        if (data == null) {
            throw new BusinessException("数据异常");
        }

        data.setTitle("湖北省普通高等学校毕业生自主创业登记表");
        String printState = printState(data.getSignState(), data.getDispatchState());
        printState = StudentSignConstants.STATE_VALID.equals(data.getState()) ? printState : StudentSignConstants.STATE_INVALID;
        data.setPrintState(printState);

        data.setXb(dictService.cacheLabel(DictConstants.TYPE_XB, data.getXb()));
        data.setXl(dictService.cacheLabel(DictConstants.TYPE_XL, data.getXl()));

        return JsonResult.ok().setData(data);
    }

    /**
     * 为导出对象设置别名和排序 排序顺序为add顺序
     *
     * @param writer ExcelWriter
     */
    public void excelAddHeaderAlias(ExcelWriter writer) {
        writer.addHeaderAlias("signState", "完成状态");
        writer.addHeaderAlias("yearId", "毕业年份");
        writer.addHeaderAlias("xh", "学号");
        writer.addHeaderAlias("xm", "姓名");
        writer.addHeaderAlias("mobile", "手机号");
        writer.addHeaderAlias("collegeName", "学院");
        writer.addHeaderAlias("majorName", "专业");
        writer.addHeaderAlias("bjhm", "班级");
        writer.addHeaderAlias("pyfs", "培养方式");
        writer.addHeaderAlias("confirmState", "毕业去向确认");
        writer.addHeaderAlias("signCategory", "就业方式");
        writer.addHeaderAlias("dispatchHiredWay", "毕业去向分类");
        writer.addHeaderAlias("dispatchGradWhere", "毕业去向");
        writer.addHeaderAlias("dispatchReportIssuedCategory", "报到证签发类别");
        writer.addHeaderAlias("dispatchReportCompany", "报到证开往单位名称");
        writer.addHeaderAlias("dispatchCompanyName", "单位名称");
        writer.addHeaderAlias("dispatchCompanyCode", "单位代码");
        writer.addHeaderAlias("dispatchCompanyMembership", "单位隶属");
        writer.addHeaderAlias("dispatchReportCompanyAddress", "所在地区");
        writer.addHeaderAlias("dealCompanyNature", "单位性质");
        writer.addHeaderAlias("dispatchJobCondition", "就业状况");
        writer.addHeaderAlias("dispatchJobCategory", "就业类别");
        writer.addHeaderAlias("waitCategory", "待就业类别");
        writer.addHeaderAlias("ext1", "扩展项1");
        writer.addHeaderAlias("ext5", "扩展项5");
        writer.addHeaderAlias("dealCompanyOrganizationCode", "单位组织机构代码(工商注册号)");
        writer.addHeaderAlias("dealCompanyIndustry", "单位行业");
        writer.addHeaderAlias("dealCompanyAddress", "实际所在地");
        writer.addHeaderAlias("dealCompanyAddressLevel", "单位所在地级别");
        writer.addHeaderAlias("dealHbIndustry", "湖北重点产业");
        writer.addHeaderAlias("dealWorkPosition", "从事岗位");
        writer.addHeaderAlias("", "岗位专业匹配");
        writer.addHeaderAlias("", "免师就业方式");
        writer.addHeaderAlias("signTime", "签约时间");
        writer.addHeaderAlias("dispatchArchivesCompany", "档案转寄单位名称");
        writer.addHeaderAlias("dispatchArchivesAddress", "档案转递地址");
        writer.addHeaderAlias("dispatchArchivesZip", "档案转递邮编");
        writer.addHeaderAlias("dispatchArchivesMobile", "档案转递联系电话");
        writer.addHeaderAlias("dispatchHkAddress", "户口去向");
        writer.addHeaderAlias("studyExtraOne", "升学附加一");
        writer.addHeaderAlias("studyExtraTwo", "升学附加二");
        writer.addHeaderAlias("dealCompanyContactName", "单位联系人");
        writer.addHeaderAlias("dealCompanyContactMobile", "单位联系方式");
        writer.addHeaderAlias("dealCompanyContactEmail", "单位电子邮箱");
        writer.addHeaderAlias("dealCompanyContactZip", "单位邮编");
        writer.addHeaderAlias("dealCompanyContactAddress", "单位地址");
        writer.addHeaderAlias("ext2", "扩展项2");
        writer.addHeaderAlias("dealWorkJobCategory", "工作职位类别");
        writer.addHeaderAlias("surveySalary", "月薪等级");
        writer.addHeaderAlias("surveyWay", "获取途径");
        writer.addHeaderAlias("surveyCompany", "对签约单位满意程度");
        writer.addHeaderAlias("surveyJob", "工作与专业相关程度调查");
        writer.addHeaderAlias("surveyMatching", "人职匹配");
        writer.addHeaderAlias("surveyOffer", "获取offer数量");
        writer.addHeaderAlias("surveySchool", "对学校就业工作满意度");
        writer.addHeaderAlias("dispatchManagedWhere", "档案托管去向");
        writer.addHeaderAlias("signWay", "签约方式");
        writer.addHeaderAlias("dealRemarks", "协议备注");
        writer.addHeaderAlias("studySchoolName", "录取院校代码");
        writer.addHeaderAlias("alterState", "档案转递单位名称是否变动");
        writer.addHeaderAlias("alterTime", "档案转递单位名称变动时间");
        writer.addHeaderAlias("alterDispatchArchivesCompany", "档案转递单位名称变动前的名称");
        writer.addHeaderAlias("dispatchArchivesNumber", "档案转递编号");
        writer.addHeaderAlias("dispatchArchivesCategory", "档案转递类型");
        writer.addHeaderAlias("dispatchArchivesName", "档案转递接收人");
        writer.addHeaderAlias("basicMark", "基层就业标志");
        writer.addHeaderAlias("abroadType", "出国出境类型");
        writer.addHeaderAlias("abroadSchool", "出国出境录取院校");
        writer.addHeaderAlias("abroadCountry", "出国出境国家/地区");
        writer.addHeaderAlias("abroadSchoolEn", "出国出境留学院校外文名称");
        writer.addHeaderAlias("abroadMajorCn", "出国出境留学专业中文名称");
        writer.addHeaderAlias("abroadMajorEn", "出国出境留学专业外文名称");
        writer.addHeaderAlias("abroadDegree", "出国出境留学学历");
        writer.addHeaderAlias("goAbroad", "是否出国出境工作");
        writer.addHeaderAlias("hkqzlx", "户口迁转类型");
        writer.addHeaderAlias("hkqzszd", "户口迁转所在地");
        writer.addHeaderAlias("hkqzdz", "户口迁转地址");

        // 只显示 writer.addHeaderAlias 的字段
        writer.setOnlyAlias(true);
    }

    /**
     * 获取学生网签毕业去向表单标签
     *
     * @param studentSign studentSign
     */
    public void getFormLabels(StudentSign studentSign) {
        Map<Object, Object> dictMap = dictService.getCacheDictMaps();
        studentSign.setXb(dictService.cacheLabel(DictConstants.TYPE_XB, studentSign.getXb(), dictMap));
        studentSign.setXl(dictService.cacheLabel(DictConstants.TYPE_XL, studentSign.getXl(), dictMap));
        studentSign.setSignCategoryLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_CATEGORY, studentSign.getSignCategory(), dictMap));
        studentSign.setSignWayLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_WAY, studentSign.getSignWay(), dictMap));
        studentSign.setSignStateLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_STATE, studentSign.getSignState(), dictMap));
        studentSign.setDispatchStateLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_DISPATCH_STATE, studentSign.getDispatchState(), dictMap));
        studentSign.setDealCompanyAddressLevelLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_DWSZDJB, studentSign.getDealCompanyAddressLevel(), dictMap));
        studentSign.setDealCompanyNatureLabel(dictService.cacheLabel(DictConstants.COMPANY_NATURE, studentSign.getDealCompanyNature(), dictMap));
        studentSign.setDealCompanyIndustryLabel(dictService.cacheLabel(DictConstants.COMPANY_INDUSTRY, studentSign.getDealCompanyIndustry(), dictMap));
        studentSign.setDealHbIndustryLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_HBZDCY, studentSign.getDealHbIndustry(), dictMap));
        studentSign.setDispatchJobCategoryLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_JYLB, studentSign.getDispatchJobCategory(), dictMap));
        studentSign.setDispatchJobConditionLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_JYZK, studentSign.getDispatchJobCondition(), dictMap));
        studentSign.setDispatchGradWhereLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_BYQX, studentSign.getDispatchGradWhere(), dictMap));
        studentSign.setDispatchReportIssuedCategoryLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_BDZQFLB, studentSign.getDispatchReportIssuedCategory(), dictMap));
        studentSign.setDispatchReportCompanyProvinceLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_SSSS, studentSign.getDispatchReportCompanyProvince(), dictMap));
        studentSign.setDispatchReportCompanyAddressLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_BDZQWDWSZD, studentSign.getDispatchReportCompanyAddress(), dictMap));
        studentSign.setDispatchCompanyMembershipLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_DWLS, studentSign.getDispatchCompanyMembership(), dictMap));
        studentSign.setSurveyStartingSalaryLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_YDXC, studentSign.getSurveyStartingSalary(), dictMap));
        studentSign.setSurveyPositionLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_GZZWLB, studentSign.getSurveyPosition(), dictMap));
        studentSign.setSurveyWayLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_XQTJ, studentSign.getSurveyWay(), dictMap));
        studentSign.setSurveyCompanyLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_MYCD, studentSign.getSurveyCompany(), dictMap));
        studentSign.setSurveyJobLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_XGCD, studentSign.getSurveyJob(), dictMap));
        studentSign.setSurveyMatchingLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_RZPP, studentSign.getSurveyMatching(), dictMap));
        studentSign.setSurveyOfferLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_OFFER, studentSign.getSurveyOffer(), dictMap));
        studentSign.setSurveySchoolLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_MYD, studentSign.getSurveySchool(), dictMap));
        studentSign.setSurveySalaryLabel(dictService.cacheLabel(DictConstants.TYPE_SIGN_YXDJ, studentSign.getSurveySalary(), dictMap));
        studentSign.setTerminationTitleLabel(dictService.cacheLabel(DictConstants.TYPE_TERMINATION_TITLE, studentSign.getTerminationTitle(), dictMap));
    }

    /**
     * 获取学生网签毕业去向表单字典
     *
     * @return 字典map集合
     */
    public Map<String, List<Dict>> getFormMap() {
        Map<String, List<Dict>> map = new HashMap<>();
        // 直接读取所有redis字典数据
        Map<Object, Object> dictMap = dictService.getCacheDictMaps();
        for (String type : StudentSignConstants.FORM_DICT_TYPES) {
            map.put(StrUtil.toCamelCase(type), dictService.cacheList(type, dictMap));
        }
        return map;
    }


    /**
     * 报到证开往湖北省人才服务局
     *
     * @param studentSign studentSign
     */
    public void dispatchHiredWayHuBei(StudentSign studentSign) {
        studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_PQ);
        studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_DLDBD);
        studentSign.setDispatchReportCompany("湖北省人才服务局");
        studentSign.setDispatchReportCompanyProvince("4201");
        studentSign.setDispatchReportCompanyAddress("420100");
        studentSign.setDispatchArchivesCompany("湖北省人才服务局");
        studentSign.setDispatchArchivesAddress("武汉市武昌区东湖路特1号湖北省人才服务局");
        studentSign.setDispatchArchivesZip("430071");
        studentSign.setDispatchArchivesMobile("027-87257963");
        studentSign.setDispatchCompanyMembership("9150");
        studentSign.setDispatchCompanyCode("9150");
    }

    /**
     * 报到证开往武汉人才中心中南财经政法大学分市场（非武汉生源毕业生）
     *
     * @param studentSign studentSign
     */
    public void dispatchHiredWayWuHan(StudentSign studentSign) {
        studentSign.setDispatchGradWhere(StudentSignConstants.SIGN_BYQX_PQ);
        studentSign.setDispatchReportIssuedCategory(StudentSignConstants.SIGN_BDZQFLB_DLDBD);
        studentSign.setDispatchReportCompany("武汉市人才服务中心");
        studentSign.setDispatchReportCompanyProvince("4201");
        studentSign.setDispatchReportCompanyAddress("420100");
        studentSign.setDispatchArchivesCompany("武汉人才服务中心中南财经政法大学分市场");
        studentSign.setDispatchArchivesAddress("中南财经政法大学南湖校区新体育场东北通道2楼");
        studentSign.setDispatchArchivesZip("430073");
        studentSign.setDispatchArchivesMobile("027-88387047");
        studentSign.setDispatchCompanyMembership("4201");
        studentSign.setDispatchCompanyCode("4201");
        studentSign.setDispatchArchivesName("李老师");
        studentSign.setDispatchArchivesCategory("2");
    }

    /**
     * 升学录取院校是中南财经政法大学并且毕业去向分类档案去往录取院校
     * @param studentSign studentSign
     */
    private void dispatchHiredWaySxZuel(StudentSign studentSign) {
        // 非中南财经政法大学什么都不做
        if (!"10520".equals(studentSign.getStudySchoolName())) {
            return;
        }

        studentSign.setDispatchReportCompany("中南财经政法大学研究生档案室");
        studentSign.setDispatchArchivesCompany("中南财经政法大学研究生档案室");
        studentSign.setDispatchReportCompanyProvince("4201");
        studentSign.setDispatchReportCompanyAddress("420100");
        studentSign.setDispatchArchivesAddress("湖北省武汉市东湖新技术开发区南湖大道182号中南财经政法大学文治楼309");
        studentSign.setDispatchArchivesZip("430073");
        studentSign.setDispatchArchivesMobile("027-88386904");
        studentSign.setDispatchCompanyMembership("4201");
        studentSign.setDispatchCompanyCode("4201");
        studentSign.setDispatchArchivesName("程余庆");
        studentSign.setDispatchArchivesCategory("4");
    }

    /**
     * 清空派遣信息
     *
     * @param studentSign studentSign
     */
    public void dispatchClear(StudentSign studentSign) {
        studentSign.setDispatchGradWhere("");
        studentSign.setDispatchReportIssuedCategory("");
        studentSign.setDispatchReportCompany("");
        studentSign.setDispatchReportCompanyProvince("");
        studentSign.setDispatchReportCompanyAddress("");
        studentSign.setDispatchArchivesCompany("");
        studentSign.setDispatchArchivesAddress("");
        studentSign.setDispatchArchivesZip("");
        studentSign.setDispatchArchivesMobile("");
        studentSign.setDispatchCompanyMembership("");
        studentSign.setDispatchCompanyCode("");
        studentSign.setDispatchArchivesName("");
    }

    /**
     * 设置扩展项等学生提交后隐性扩展项、逻辑值
     * 设置单位代码 单位代码在选择录用方式后还为空就取 报到证迁往单位所属省份 湖北省内为地市
     * 设置单位隶属 单位隶属在选择录用方式后还为空就取 报到证迁往单位所属省份 湖北省内为地市
     * 协议就业扩展项设置：首先报到证签往单位名称不等于 签约单位名称 并且不等于 实际单位名称。然后报到证地区和签约单位地区前4为地区编码一致认定为一个区域。一个区域设置扩展项1=实际单位名称、否则设置扩展项5=实际单位名称
     *
     * @param studentSign studentSign
     */
    @Override
    public void setExt(StudentSign studentSign, Student student) {
        // 单位代码为空 重新设置
        if (StrUtil.isBlank(studentSign.getDispatchCompanyCode())) {
            studentSign.setDispatchCompanyCode(studentSign.getDispatchCompanyMembership());
        }

        // 单位隶属为空 重新设置
        if (StrUtil.isBlank(studentSign.getDispatchCompanyMembership())) {
            studentSign.setDispatchCompanyMembership(studentSign.getDispatchReportCompanyProvince());
        }

        // 设置单位名称=报到证迁往单位所属省份 协议就业和升学各自逻辑会覆盖此属性
        studentSign.setDispatchCompanyName(studentSign.getDispatchReportCompany());

        if (StudentSignConstants.SIGN_CATEGORY_XYJY.equals(studentSign.getSignCategory())) {
            String s1 = studentSign.getDispatchReportCompany();
            String s2 = studentSign.getDispatchReportCompanyAddress();
            String s3 = studentSign.getDealSignCompanyName();
            String s4 = studentSign.getDealCompanyName();
            String s5 = studentSign.getDealCompanyAddress();

            if (!StrUtil.isBlank(s1) && !StrUtil.isBlank(s2) && !StrUtil.isBlank(s3) && !StrUtil.isBlank(s4) && !StrUtil.isBlank(s5)
                    && !s1.equals(s3) && !s1.equals(s4)) {
                String address2 = StrUtil.sub(s2, 0, 4);
                String address5 = StrUtil.sub(s5, 0, 4);
                // 地区编码前4位一样认定为一个区域
                if (address2.equals(address5)) {
                    studentSign.setExt1(s4);
                } else {
                    studentSign.setExt5(s4);
                }
            }

            if (StudentConstants.PYFS_DX.equals(student.getPyfs())) {
                studentSign.setExt2("定向");
            }
            if (StudentConstants.PYFS_WP.equals(student.getPyfs())) {
                studentSign.setExt2("委培");
            }

            studentSign.setDispatchJobCondition(StudentSignConstants.SIGN_JYZK_XYJY);
            studentSign.setDispatchCompanyName(studentSign.getDealSignCompanyName());
            studentSign.setDispatchManagedWhere(studentSign.getDispatchArchivesCompany());
        }

        if (StudentSignConstants.SIGN_CATEGORY_LHJY.equals(studentSign.getSignCategory())) {
            studentSign.setExt5(studentSign.getDealCompanyName());
        }

        if (StudentSignConstants.SIGN_CATEGORY_ZZCY.equals(studentSign.getSignCategory())) {
            studentSign.setExt5(studentSign.getVentureCompanyName());
        }

        if (StudentSignConstants.SIGN_CATEGORY_ZYZY.equals(studentSign.getSignCategory())) {
            studentSign.setExt5(studentSign.getFreeWorkContent());
        }

        if (StudentSignConstants.SIGN_CATEGORY_SX.equals(studentSign.getSignCategory())) {
            studentSign.setDispatchCompanyName(dictService.cacheLabel(DictConstants.TYPE_DC_LQYXDM, studentSign.getStudySchoolName()));
            studentSign.setDispatchCompanyCode("0010");
            studentSign.setDispatchCompanyMembership("10");
            studentSign.setDispatchReportCompanyAddress(studentSign.getStudySchoolAddress());
            studentSign.setDealCompanyIndustry("42");
            studentSign.setDealCompanyAddress(studentSign.getStudySchoolAddress());
            studentSign.setDealCompanyAddressLevel(studentSign.getStudySchoolAddressLevel());
            studentSign.setDealWorkJobCategory("90");

            String way = studentSign.getDispatchHiredWay();

            if (StudentSignConstants.LYFS_10.equals(way)) {
                studentSign.setExt5("本科第二学位");
            } else {
                studentSign.setExt5("");
            }

            if (StudentSignConstants.LYFS_11.equals(way) || StudentSignConstants.LYFS_12.equals(way)) {
                studentSign.setExt5(studentSign.getStudySchoolName() + "非全日制");
            }

            if (StudentSignConstants.LYFS_10.equals(way)
                    || StudentSignConstants.LYFS_11.equals(way)
                    || StudentSignConstants.LYFS_12.equals(way)
                    || StudentSignConstants.LYFS_14.equals(way)) {
                studentSign.setStudyExtraOne("统考");
            }
            if (StudentSignConstants.LYFS_13.equals(way)) {
                studentSign.setStudyExtraOne("保送");
            }

            studentSign.setStudyExtraTwo(dictService.cacheLabel(DictConstants.TYPE_SIGN_STUDY_SCHOOL_CROSS_MAJOR, studentSign.getStudySchoolCrossMajor()));
        }

        if (StudentSignConstants.SIGN_CATEGORY_CGCJ.equals(studentSign.getSignCategory())) {
            String abroadCountry = !StrUtil.isBlank(studentSign.getAbroadCountry()) ? studentSign.getAbroadCountry() : "";
            String abroadSchool = !StrUtil.isBlank(studentSign.getAbroadSchool()) ? studentSign.getAbroadSchool() : "";
            studentSign.setExt5(abroadCountry + abroadSchool);
        }

        // 就业类别等于选调生 扩展项1等于选调生
        if (StudentSignConstants.SIGN_JYLB_XDS.equals(studentSign.getDispatchJobCategory())) {
            studentSign.setExt1("选调生");
        }

        // 待就业没有特殊要求
    }

    /**
     * 构建学院审核表单的一些按钮元素
     * 按钮有效状态
     * 按钮文字
     * 显示基本审核状态 / 显示解约或改派状态
     * 设置默认状态值
     *
     * @param studentSign
     * @return
     */
    public StudentSignCollegeSubmitVO buildCollegeSubmit(StudentSign studentSign) {
        StudentSignCollegeSubmitVO submitVO = new StudentSignCollegeSubmitVO();

        submitVO.setCollegeBtn(false);
        submitVO.setCollegeBtnText(StudentSignCollegeSubmitVO.BTN_TEXT_HAS);
        submitVO.setCollegeState("0");

        if (StudentSignConstants.SIGN_STATE_STUDENT_AGREED.equals(studentSign.getSignState())) {
            submitVO.setCollegeBtn(true);
            submitVO.setCollegeBtnText(StudentSignCollegeSubmitVO.BTN_TEXT_SUBMIT);
            submitVO.setCollegeState("1");
            submitVO.setSignStateShow(true);
        }
        if (StudentSignConstants.SIGN_STATE_STUDENT_SUBMIT_UPLOAD.equals(studentSign.getSignState())) {
            submitVO.setCollegeBtn(false);
            submitVO.setCollegeState("1");
            submitVO.setCollegeBtnText("已提交,待上传打印表");
        }
        if (StudentSignConstants.SIGN_STATE_STUDENT_SUBMIT.equals(studentSign.getSignState())) {
            submitVO.setCollegeBtn(true);
            submitVO.setCollegeBtnText(StudentSignCollegeSubmitVO.BTN_TEXT_SUBMIT);
            submitVO.setCollegeState("1");
            submitVO.setSignStateShow(true);
        }
        if (StudentSignConstants.SIGN_STATE_STUDENT_TERMINATION.equals(studentSign.getSignState())) {
            submitVO.setCollegeBtn(true);
            submitVO.setCollegeBtnText(StudentSignCollegeSubmitVO.BTN_TEXT_SUBMIT);
            submitVO.setCollegeState("2");
            submitVO.setSignStateShow(true);

            if (UserConstants.USER_TYPE_COLLEGE.equals(studentSign.getUserType())) {
                submitVO.setCollegeBtn(false);
                submitVO.setCollegeBtnText(StudentSignCollegeSubmitVO.BTN_TEXT_SUBMIT);
                submitVO.setCollegeState("0");
                submitVO.setSignStateShow(false);
            }
        }
        if (StudentSignConstants.SIGN_STATE_COLLEGE_TERMINATION_PASS.equals(studentSign.getSignState())) {
            submitVO.setCollegeBtn(true);
            submitVO.setCollegeBtnText(StudentSignCollegeSubmitVO.BTN_TEXT_SUBMIT);
            submitVO.setCollegeState("2");
            submitVO.setSignStateShow(true);

            if (UserConstants.USER_TYPE_TEACHER.equals(studentSign.getUserType())) {
                submitVO.setCollegeBtn(false);
                submitVO.setCollegeBtnText(StudentSignCollegeSubmitVO.BTN_TEXT_SUBMIT);
                submitVO.setCollegeState("0");
                submitVO.setSignStateShow(false);
            }
        }

        if (StudentSignConstants.DISPATCH_STATE_STUDENT_SUBMIT.equals(studentSign.getDispatchState())) {
            submitVO.setDispatchStateShow(true);
            if (StudentSignConstants.SIGN_STATE_STUDENT_SUBMIT_UPLOAD.equals(studentSign.getSignState())) {
                submitVO.setDispatchStateShow(false);
            }
        }
        if (StudentSignConstants.DISPATCH_STATE_EDIT_STUDENT_SUBMIT.equals(studentSign.getDispatchState())) {
            submitVO.setCollegeBtn(true);
            submitVO.setCollegeBtnText(StudentSignCollegeSubmitVO.BTN_TEXT_SUBMIT);
            submitVO.setCollegeState("2");
            submitVO.setDispatchStateShow(true);
        }

        if (StudentSignConstants.SIGN_STATE_COLLEGE_FAIL.equals(studentSign.getSignState())) {
            submitVO.setCollegeBtn(false);
        }
        if (StudentSignConstants.SIGN_STATE_COLLEGE_TERMINATION_FAIL.equals(studentSign.getSignState())) {
            submitVO.setCollegeBtn(false);
        }
        if (StudentSignConstants.DISPATCH_STATE_COLLEGE_FAIL.equals(studentSign.getDispatchState())) {
            submitVO.setCollegeBtn(false);
        }

        return submitVO;
    }

    @Override
    public JsonResult signStatistics(StudentSignStatistics studentSignStatistics) {
        List<StudentSign> studentSignList = baseMapper.listStatistics(studentSignStatistics);

        int studentCount = studentSignList.size();
        int studentSignCount = 0;
        int studentNotSignCount = 0;

        int dealCount = 0;
        int agileCount = 0;
        int ventureCount = 0;
        int freeCount = 0;
        int studyCount = 0;
        int abroadCount = 0;
        int waitCount = 0;

        for (StudentSign studentSign : studentSignList) {
            if (StudentSignConstants.SIGN_STATE_SCHOOL_PASS.equals(studentSign.getSignState()) &&
                    (StudentSignConstants.DISPATCH_STATE_SCHOOL_PASS.equals(studentSign.getDispatchState())
                            || StudentSignConstants.DISPATCH_STATE_EDIT_SCHOOL_PASS.equals(studentSign.getDispatchState()))
            ) {
                studentSignCount++;

                if (StudentSignConstants.SIGN_CATEGORY_XYJY.equals(studentSign.getSignCategory())) {
                    dealCount++;
                }
                if (StudentSignConstants.SIGN_CATEGORY_LHJY.equals(studentSign.getSignCategory())) {
                    agileCount++;
                }
                if (StudentSignConstants.SIGN_CATEGORY_ZZCY.equals(studentSign.getSignCategory())) {
                    ventureCount++;
                }
                if (StudentSignConstants.SIGN_CATEGORY_ZYZY.equals(studentSign.getSignCategory())) {
                    freeCount++;
                }
                if (StudentSignConstants.SIGN_CATEGORY_SX.equals(studentSign.getSignCategory())) {
                    studyCount++;
                }
                if (StudentSignConstants.SIGN_CATEGORY_CGCJ.equals(studentSign.getSignCategory())) {
                    abroadCount++;
                }
                if (StudentSignConstants.SIGN_CATEGORY_DJY.equals(studentSign.getSignCategory())) {
                    waitCount++;
                }
            } else {
                studentNotSignCount++;
            }
        }

        BigDecimal dealPercent = studentCount != 0 ? NumberUtil.round(NumberUtil.div(dealCount, studentCount) * 100, 2) : new BigDecimal(0);
        BigDecimal agilePercent = studentCount != 0 ? NumberUtil.round(NumberUtil.div(agileCount, studentCount) * 100, 2) : new BigDecimal(0);
        BigDecimal venturePercent = studentCount != 0 ? NumberUtil.round(NumberUtil.div(ventureCount, studentCount) * 100, 2) : new BigDecimal(0);
        BigDecimal freePercent = studentCount != 0 ? NumberUtil.round(NumberUtil.div(freeCount, studentCount) * 100, 2) : new BigDecimal(0);
        BigDecimal studyPercent = studentCount != 0 ? NumberUtil.round(NumberUtil.div(studyCount, studentCount) * 100, 2) : new BigDecimal(0);
        BigDecimal abroadPercent = studentCount != 0 ? NumberUtil.round(NumberUtil.div(abroadCount, studentCount) * 100, 2) : new BigDecimal(0);
        BigDecimal waitPercent = studentCount != 0 ? NumberUtil.round(NumberUtil.div(waitCount, studentCount) * 100, 2) : new BigDecimal(0);
        BigDecimal notSignPercent = studentCount != 0 ? NumberUtil.round(NumberUtil.div(studentNotSignCount, studentCount) * 100, 2) : new BigDecimal(0);

        studentSignStatistics.setStudentCount(studentCount);
        studentSignStatistics.setStudentSignCount(studentSignCount);
        studentSignStatistics.setStudentNotSignCount(studentNotSignCount);

        List<ValueName> pies = new ArrayList<>();
        pies.add(new ValueName(dealPercent, "协议就业：" + dealPercent + "%(" + dealCount + ")"));
        pies.add(new ValueName(agilePercent, "灵活就业：" + agilePercent + "%(" + agileCount + ")"));
        pies.add(new ValueName(venturePercent, "自主创业：" + venturePercent + "%(" + ventureCount + ")"));
        pies.add(new ValueName(freePercent, "自由职业：" + freePercent + "%(" + freeCount + ")"));
        pies.add(new ValueName(studyPercent, "升学(境内)：" + studyPercent + "%(" + studyCount + ")"));
        pies.add(new ValueName(abroadPercent, "出国出境：" + abroadPercent + "%(" + abroadCount + ")"));
        pies.add(new ValueName(waitPercent, "待就业：" + waitPercent + "%(" + waitCount + ")"));
        pies.add(new ValueName(notSignPercent, "未签约(未登记)：" + notSignPercent + "%(" + studentNotSignCount + ")"));
        studentSignStatistics.setPies(pies);

        return JsonResult.ok().setData(studentSignStatistics);
    }

    @Override
    public JsonResult allSignStatistics(StudentSignStatistics studentSignStatistics, List<College> colleges) {
        Map<String, Object> result = new HashMap<>();

        List<StudentCollegeVO> studentCollegeVOS = studentService.studentCollegeList(Integer.parseInt(studentSignStatistics.getYearId()));

        for (College c : colleges) {

            StudentSignStatistics item = new StudentSignStatistics();

            int studentCount = 0;

            for (StudentCollegeVO vo : studentCollegeVOS) {
                if (vo.getCollegeCode().equals(c.getCode())) {
                    studentCount = vo.getStudentCount();
                    break;
                }
            }
            item.setCollegeCode(c.getCode());

            List<StudentSign> studentSignList = baseMapper.listStatistics(studentSignStatistics);

            int studentSignCount = 0;
            int studentNotSignCount = 0;


            for (StudentSign studentSign : studentSignList) {
                if (StudentSignConstants.SIGN_STATE_SCHOOL_PASS.equals(studentSign.getSignState()) &&
                        (StudentSignConstants.DISPATCH_STATE_SCHOOL_PASS.equals(studentSign.getDispatchState())
                                || StudentSignConstants.DISPATCH_STATE_EDIT_SCHOOL_PASS.equals(studentSign.getDispatchState()))
                ) {
                    studentSignCount++;
                } else {
                    studentNotSignCount++;
                }
            }
            item.setStudentCount(studentCount);
            item.setStudentSignCount(studentSignCount);
            item.setStudentNotSignCount(studentNotSignCount);

            result.put(c.getName(), item);
        }

        return JsonResult.ok().setData(result);
    }

    @Override
    public HomeData homeData(Integer yearId) {
        HomeData homeData = new HomeData();

        Date now = new Date();
        Date startDate = DateUtil.beginOfDay(now);
        Date endDate = DateUtil.endOfDay(now);

        int signNowInvitationBkCount = 0;
        int signNowInvitationYjsCount = 0;
        int signNowInvitationCount = 0;
        StudentSignHomeVO signInvitedTimeVO = new StudentSignHomeVO();
        signInvitedTimeVO.setYearId(yearId);
        signInvitedTimeVO.setSignInvitedTimeStart(startDate);
        signInvitedTimeVO.setSignInvitedTimeEnd(endDate);
        List<StudentSignHomeVO> signInvitedTimeVOList = baseMapper.listHome(signInvitedTimeVO);
        for (StudentSignHomeVO signInvitedTime : signInvitedTimeVOList) {
            signNowInvitationCount++;
            if (StudentConstants.STUDENT_DEGREE_BK.equals(signInvitedTime.getDegree())) {
                signNowInvitationBkCount++;
            }
            if (StudentConstants.STUDENT_DEGREE_YJS.equals(signInvitedTime.getDegree())) {
                signNowInvitationYjsCount++;
            }
        }
        homeData.setSignNowInvitationBkCount(signNowInvitationBkCount);
        homeData.setSignNowInvitationYjsCount(signNowInvitationYjsCount);
        homeData.setSignNowInvitationCount(signNowInvitationCount);


        int signNowAgencyBkCount = 0;
        int signNowAgencyYjsCount = 0;
        int signNowAgencyCount = 0;
        StudentSignHomeVO signTimeVO = new StudentSignHomeVO();
        signTimeVO.setYearId(yearId);
        signTimeVO.setSignTimeStart(startDate);
        signTimeVO.setSignTimeEnd(endDate);
        List<StudentSignHomeVO> signTimeVOList = baseMapper.listHome(signTimeVO);
        for (StudentSignHomeVO signTime : signTimeVOList) {
            signNowAgencyCount++;
            if (StudentConstants.STUDENT_DEGREE_BK.equals(signTime.getDegree())) {
                signNowAgencyBkCount++;
            }
            if (StudentConstants.STUDENT_DEGREE_YJS.equals(signTime.getDegree())) {
                signNowAgencyYjsCount++;
            }
        }
        homeData.setSignNowAgencyBkCount(signNowAgencyBkCount);
        homeData.setSignNowAgencyYjsCount(signNowAgencyYjsCount);
        homeData.setSignNowAgencyCount(signNowAgencyCount);

        int signWaitBkCount = 0;
        int signWaitYjsCount = 0;
        int signWaitCount = 0;
        StudentSignHomeVO waitVO = new StudentSignHomeVO();
        waitVO.setYearId(yearId);
        waitVO.setCategory(StudentSignConstants.ADMIN_LIST_CATEGORY_1);
        List<StudentSignHomeVO> waitVOList = baseMapper.listHome(waitVO);
        for (StudentSignHomeVO wait : waitVOList) {
            signWaitCount++;
            if (StudentConstants.STUDENT_DEGREE_BK.equals(wait.getDegree())) {
                signWaitBkCount++;
            }
            if (StudentConstants.STUDENT_DEGREE_YJS.equals(wait.getDegree())) {
                signWaitYjsCount++;
            }
        }
        homeData.setSignWaitBkCount(signWaitBkCount);
        homeData.setSignWaitYjsCount(signWaitYjsCount);
        homeData.setSignWaitCount(signWaitCount);

        return homeData;
    }

    /**
     * 验证违约金
     *
     * @param studentSign studentSign
     * @return code 0正常 1不正常
     */
    private JsonResult verifyDealPenalty(StudentSign studentSign) {
        if (!StudentSignConstants.SIGN_CATEGORY_XYJY.equals(studentSign.getSignCategory())) {
            return JsonResult.ok();
        }

        if ("0".equals(studentSign.getDealPenalty())) {
            return JsonResult.ok();
        }

        int dealPenalty = Convert.toInt(studentSign.getDealPenalty(), -1);
        if (dealPenalty == -1) {
            return JsonResult.error("违约金格式不正确");
        }

        int dealFormalSalary = Convert.toInt(studentSign.getDealFormalSalary(), -1);
        if (dealFormalSalary == -1) {
            return JsonResult.error("违约金不为0，起薪(转正后)必须是数字");
        }

        StudentSignSet set = studentSignSetService.get();
        if (set == null) {
            return JsonResult.error("签约设置异常，请联系管理员");
        }

        if (dealPenalty > set.getPenalty()) {
            return JsonResult.error("违约金超过上限：" + set.getPenalty());
        }

        if (dealPenalty > dealFormalSalary * set.getPenaltyMultiple()) {
            return JsonResult.error("违约金不超过起薪(转正后)的 " + set.getPenaltyMultiple() + "倍");
        }

        return JsonResult.ok();
    }

    /**
     * 验证湖北重点产业 地区必须是湖北省内
     *
     * @param studentSign studentSign
     * @return JsonResult
     */
    private JsonResult verifyDealHbIndustry(StudentSign studentSign) {
        if (StudentSignConstants.HB_FALSE.equals(studentSign.getDealHbIndustry())) {
            return JsonResult.ok();
        }

        String errorMsg = "单位地区不属于湖北省，湖北重点产业只能选择否";
        if (StudentSignConstants.SIGN_CATEGORY_XYJY.equals(studentSign.getSignCategory())) {
            if (!"42".equals(StrUtil.sub(studentSign.getDealCompanyAddress(), 0, 2))) {
                return JsonResult.error(errorMsg);
            }
        }
        if (StudentSignConstants.SIGN_CATEGORY_LHJY.equals(studentSign.getSignCategory())) {
            if (!"42".equals(StrUtil.sub(studentSign.getDealCompanyAddress(), 0, 2))) {
                return JsonResult.error(errorMsg);
            }
        }
        if (StudentSignConstants.SIGN_CATEGORY_ZYZY.equals(studentSign.getSignCategory())) {
            if (!"42".equals(StrUtil.sub(studentSign.getFreeWorkAddress(), 0, 2))) {
                return JsonResult.error(errorMsg);
            }
        }
        if (StudentSignConstants.SIGN_CATEGORY_ZZCY.equals(studentSign.getSignCategory())) {
            if (!"42".equals(StrUtil.sub(studentSign.getDealCompanyAddress(), 0, 2))) {
                return JsonResult.error(errorMsg);
            }
        }

        return JsonResult.ok();
    }

    /**
     * 计算打印表是否有效状态
     *
     * @param signState     签约状态
     * @param dispatchState 派遣状态
     * @return 有效/无效
     */
    private String printState(String signState, String dispatchState) {
        if ((StudentSignConstants.SIGN_STATE_COLLEGE_PASS.equals(signState)
                || StudentSignConstants.SIGN_STATE_SCHOOL_PASS.equals(signState))
                && (StudentSignConstants.DISPATCH_STATE_COLLEGE_PASS.equals(dispatchState)
                || StudentSignConstants.DISPATCH_STATE_SCHOOL_PASS.equals(dispatchState))
        ) {
            return StudentSignConstants.STATE_VALID;
        }
        return StudentSignConstants.STATE_INVALID;
    }

    /**
     * 基于空白协议 验证学生能否被邀约、应约、自主录入
     *
     * @param studentId 学生ID
     * @return code0可以 1不可以
     */
    private JsonResult blankVerify(Integer studentId) {
        List<StudentSignBlank> list = studentSignBlankMapper.selectList(new QueryWrapper<StudentSignBlank>()
                .eq("student_id", studentId)
        );

        if (list == null || list.size() == 0) {
            return JsonResult.ok();
        }

        boolean b = true;
        for (StudentSignBlank blank : list) {
            if (!StudentSignBlankConstants.CHECK_STATE_COLLEGE_FAIL.equals(blank.getCheckState())) {
                b = false;
                break;
            }
        }

        if (b) {
            return JsonResult.ok();
        }
        return JsonResult.error("无法操作，该学生当前有空白协议正在进行中");
    }

    @Override
    public JsonResult verifyCompanyView(Integer id, Integer loginUserId) {
        StudentSign studentSign = baseMapper.selectById(id);
        if (null == studentSign) {
            return JsonResult.error("信息异常");
        }

        Company company = companyService.getByUserId(loginUserId);
        if (null == company) {
            return JsonResult.error("单位异常");
        }

        if (company.getId().equals(studentSign.getCompanyId())) {
            return JsonResult.ok();
        }

        return JsonResult.error("非法操作，不可查看签约信息");
    }

    /**
     * 验证邀约过期时间
     * 输出按钮状态和文字
     *
     * @param studentSign StudentSign
     * @return JsonResult
     */
    private JsonResult verifySignExpiredTime(StudentSign studentSign) {
        if (studentSign.getSignExpiredTime() == null) {
            return JsonResult.error("邀约过期时间异常").put("expiredBtn", false).put("expiredBtnMsg", "无邀约过期时间,不可应约");
        } else {
            if (new Date().getTime() > studentSign.getSignExpiredTime().getTime()) {
                return JsonResult.error("邀约已过期").put("expiredBtn", false).put("expiredBtnMsg", "邀约已过期");
            }
        }
        return JsonResult.ok().put("expiredBtn", true).put("expiredBtnMsg", "应约");
    }

    @Override
    public JsonResult resetSignCategoryByCollege(Integer id, Integer loginUserId) {
        if (id == null) {
            throw new BusinessException("参数异常");
        }

        StudentSign studentSign = baseMapper.selectById(id);
        if (studentSign == null) {
            throw new BusinessException("数据异常");
        }

        if (StudentSignConstants.SIGN_CATEGORY_XYJY.equals(studentSign.getSignCategory())) {
            throw new BusinessException("只能重置非协议就业");
        }

        boolean b = clearSignCategory(studentSign);
        if (b) {
            studentRecordService.save(
                    new StudentRecord(loginUserId, studentSign.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, StudentConstants.RECORD_OPERATE_COLLEGE_RESET)
            );
            return JsonResult.ok("重置成功");
        }

        return JsonResult.error("重置失败");
    }

    @Override
    public JsonResult resetSignCategoryBySchool(Integer id, Integer loginUserId) {
        if (id == null) {
            throw new BusinessException("参数异常");
        }

        StudentSign studentSign = baseMapper.selectById(id);
        if (studentSign == null) {
            throw new BusinessException("数据异常");
        }

        boolean b = clearSignCategory(studentSign);
        if (b) {
            studentRecordService.save(
                    new StudentRecord(loginUserId, studentSign.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, StudentConstants.RECORD_OPERATE_SCHOOL_RESET)
            );
            return JsonResult.ok("重置成功");
        }

        return JsonResult.error("重置失败");
    }

    @Override
    public void resetSignCategoryByBlank(StudentSign studentSign, Integer loginUserId) {
        if (!clearSignCategory(studentSign)) {
            throw new BusinessException("重置就业方式时失败");
        }

        studentRecordService.save(
                new StudentRecord(loginUserId, studentSign.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, "空白协议重置就业方式")
        );
    }

    private boolean clearSignCategory(StudentSign studentSign) {
        StudentSign sign = new StudentSign();
        sign.setId(studentSign.getId());
        sign.setState(StudentSignConstants.STATE_INVALID);
        if (baseMapper.updateById(sign) > 0) {
            // 清空学生就业方式
            studentService.update(new LambdaUpdateWrapper<Student>()
                    .set(Student::getSignCategory, "")
                    .eq(Student::getId, studentSign.getStudentId())
            );
            return true;
        }
        return false;
    }

    @Override
    public PageResult<StudentSignRecordVO> listSignRecord(PageParam<StudentSignRecordVO> pageParam) {
        return new PageResult<>(baseMapper.listSignRecord(pageParam), pageParam.getTotal());
    }

    @Override
    public PageResult<StudentSignAlumniVO> listAlumniPage(PageParam<StudentSign> pageParam) {
        return new PageResult<>(baseMapper.listAlumniPage(pageParam), pageParam.getTotal());
    }

    @Override
    public List<Student> screenStudentSign(List<Student> studentList) {
        List<Integer> studentIds = new ArrayList<>();
        studentList.forEach(item -> studentIds.add(item.getId()));

        // 完成毕业去向登记信息 排除待就业
        List<StudentSign> studentSignList = baseMapper.selectList(new QueryWrapper<StudentSign>()
                .select("id, student_id")
                .in("student_id", studentIds)
                .eq("state", StudentSignConstants.STATE_VALID)
                .eq("sign_state", StudentSignConstants.SIGN_STATE_SCHOOL_PASS)
                .eq("dispatch_state", StudentSignConstants.DISPATCH_STATE_SCHOOL_PASS)
                .ne("sign_category", StudentSignConstants.SIGN_CATEGORY_DJY)
        );

        List<Student> removeList = new ArrayList<>();
        for (Student student : studentList) {
            for (StudentSign studentSign : studentSignList) {
                if (student.getId().equals(studentSign.getStudentId())) {
                    removeList.add(student);
                }
            }
        }
        studentList.removeAll(removeList);

        return studentList;
    }

    @Override
    public List<StudentSignStatisticsCollegeVO> collegeStudentSignCount(Integer yearId, String xl, String tks, String date1, String date2) {
        return baseMapper.collegeStudentSignCount(yearId, xl, tks, date1, date2);
    }

    @Override
    public List<StudentSignStatisticsCollegeVO> majorStudentSignCount(Integer yearId, String xl) {
        return baseMapper.majorStudentSignCount(yearId, xl);
    }

    @Override
    public List<StudentSignStatisticsCollegeVO> mzStudentSignCount(Integer yearId, String xl, String tks) {
        return baseMapper.mzStudentSignCount(yearId, xl, tks);
    }

    @Override
    public StudentSignStatisticsCollegeVO signCount(Integer yearId) {
        return baseMapper.signCount(yearId);
    }

    @Override
    public List<StudentSignConfirmVO> studentSignConfirmList(Integer yearId) {
        return baseMapper.studentSignConfirmList(yearId);
    }

    @Override
    public JsonResult importNumber(MultipartFile file) {
        StringBuilder sb = new StringBuilder();
        try {
            // 读取Excel
            int startRow = 1;
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream(), 0);
            List<List<Object>> list = reader.read(startRow);

            // 进行非空和重复检查
            sb.append(CoreUtil.excelCheckBlank(list, startRow, 0));
            sb.append(CoreUtil.excelCheckRepeat(list, startRow, 0));
            if (!sb.toString().isEmpty()) {
                return JsonResult.error(sb.toString());
            }

            // 进行数据库层面检查
            List<StudentSign> studentSignList = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                List<Object> objects = list.get(i);
                String xh = String.valueOf(objects.get(0));
                String number = objects.size() >= 2 ? String.valueOf(objects.get(1)) : "";

                Student student = studentService.getByXh(xh);

                if (student == null) {
                    sb.append("第");
                    sb.append(i + startRow + 1);
                    sb.append("行第1");
                    sb.append("列学号不存在;\r\n");
                } else {
                    StudentSign studentSign = new StudentSign();
                    studentSign.setStudentId(student.getId());
                    studentSign.setDispatchArchivesNumber(number);
                    studentSignList.add(studentSign);
                }

            }

            if (!sb.toString().isEmpty()) {
                return JsonResult.error(sb.toString());
            }

            int okNum = 0, errorNum = 0;
            for (StudentSign studentSign : studentSignList) {
                StudentSign update = new StudentSign();
                update.setDispatchArchivesNumber(studentSign.getDispatchArchivesNumber());
                int i = baseMapper.update(update, new LambdaUpdateWrapper<StudentSign>()
                        .eq(StudentSign::getStudentId, studentSign.getStudentId())
                );
                if (i > 0) {
                    okNum++;
                } else {
                    errorNum++;
                }
            }
            return JsonResult.ok("导入完成，成功" + okNum + "条，失败" + errorNum + "条");
        } catch (IOException e) {
            e.printStackTrace();
        }

        return JsonResult.error("导入失败");
    }

    /**
     * 档案转递单位发生改变时记录
     *
     * @param old         原记录
     * @param studentSign 当前记录
     * @param loginUserId 操作人
     * @param alterBy     操作人类型
     */
    void alterLog(StudentSign old, StudentSign studentSign, Integer loginUserId, String alterBy) {
        boolean change = false;

        if (!StrUtil.isBlank(old.getDispatchArchivesCompany()) && !StrUtil.isBlank(studentSign.getDispatchArchivesCompany())) {
            if (!old.getDispatchArchivesCompany().equals(studentSign.getDispatchArchivesCompany())) {
                change = true;
            }
        }

        if (!StrUtil.isBlank(old.getDispatchHkAddress()) && !StrUtil.isBlank(studentSign.getDispatchHkAddress())) {
            if (!old.getDispatchHkAddress().equals(studentSign.getDispatchHkAddress())) {
                change = true;
            }
        }

        if (!StrUtil.isBlank(old.getDispatchArchivesAddress()) && !StrUtil.isBlank(studentSign.getDispatchArchivesAddress())) {
            if (!old.getDispatchArchivesAddress().equals(studentSign.getDispatchArchivesAddress())) {
                change = true;
            }
        }

        if (!change) {
            return;
        }

        studentSign.setAlterState(StudentSignConstants.ALTER_TRUE);
        studentSign.setAlterTime(new Date());

        studentSignAlterService.alterLog(old, studentSign, loginUserId, alterBy);
    }

    @Override
    public List<StudentSign> tempList() {
        return baseMapper.tempList();
    }

    @Override
    public List<StudentSign> listBigData(Integer year) {
        return baseMapper.listBigData(year);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public JsonResult choiceCompanyEdit(Integer studentSignEditId, Integer state, Integer userId) {
        StudentSignEdit studentSignEdit = studentSignEditService.getById(studentSignEditId);
        if (studentSignEdit == null) {
            return JsonResult.error("未查询到修改协议就业");
        }

        if (!userId.equals(studentSignEdit.getUserId())) {
            return JsonResult.error("异常操作");
        }

        StudentSign studentSign = baseMapper.selectById(studentSignEdit.getStudentSignId());
        if (studentSign == null) {
            return JsonResult.error("未查询到原协议就业");
        }

        switch (state) {
            // 同意 修改内容新增为新的协议内容 删除原签约 删除修改内容
            case 0:
                StudentSign insert = new StudentSign();
                BeanUtil.copyProperties(studentSignEdit, insert);
                insert.setOldId(studentSign.getId());
                baseMapper.insert(insert);
                baseMapper.deleteById(studentSign.getId());
                studentSignEditService.removeById(studentSignEdit.getId());
                studentRecordService.save(
                        new StudentRecord(userId, studentSign.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, "学生同意单位修改的协议内容")
                );
                break;
            // 不同意 删除修改协议内容
            case 1:
                studentSignEditService.removeById(studentSignEdit.getId());
                studentRecordService.save(
                        new StudentRecord(userId, studentSign.getStudentId(), StudentConstants.RECORD_TYPE_SIGN, "学生不同意单位修改的协议内容")
                );
                break;
            default:
                return JsonResult.error("状态参数不正确");
        }

        return JsonResult.ok();
    }

    /**
     * 毕业去向基础验证
     * @param studentSign studentSign
     */
    private void validateStudentSign(StudentSign studentSign) {
        // 单位联系人
        if (!StrUtil.isBlank(studentSign.getDealCompanyContactName())) {
            int length = StrUtil.length(studentSign.getDealCompanyContactName());
            if (length > 10) {
                throw new BusinessException("单位联系人字符长度不超过10位");
            }

            boolean chinese = ReUtil.isMatch(ReUtil.RE_CHINESES, studentSign.getDealCompanyContactName());
            if (!chinese) {
                throw new BusinessException("单位联系人必须是中文");
            }
        }
        // 实际单位所在地  如果选择了协议就业并且选择了出国出境，单位所在地不要求到具体区县
        if (!StrUtil.isBlank(studentSign.getDealCompanyAddress())) {
            String suf = StrUtil.subSuf(studentSign.getDealCompanyAddress(), 2);
            if(!(StrUtil.isNotBlank(studentSign.getSignCategory()) && studentSign.getSignCategory().equals(StudentSignConstants.SIGN_CATEGORY_XYJY)
                && StrUtil.isNotBlank(studentSign.getGoAbroad()) && studentSign.getGoAbroad().equals(StudentSignConstants.WORK_ABROAD))
                && "0000".equals(suf)) {
                throw new BusinessException("实际单位所在地请选择到具体区县");
            }
        }


        // 单位性质 社会统一信仰代码第一位是9 单位性质是机关或者其他事业单位 提示错误
        if (!StrUtil.isBlank(studentSign.getDealCompanyNature()) && !StrUtil.isBlank(studentSign.getDealCompanyOrganizationCode())) {
            String head = StrUtil.subPre(studentSign.getDealCompanyOrganizationCode(), 1);
            if ("9".equals(head) && ("10".equals(studentSign.getDealCompanyNature()) || "29".equals(studentSign.getDealCompanyNature()))) {
                throw new BusinessException("单位性质非机关或事业单位");
            }
        }

    }

}
